2017-06-02 58 views
-1

我有一個順序的記錄列表。該簡化的結構如下:使用LINQ從屬性值中刪除項目使用LINQ

Underline Text  Order 
-1  Header1 1 
-1  SubHeader1 2 
0   Data1  3 
-1  Header2 4 // this needs to be removed 
-1  SubHeader2 5 // this needs to be removed 
-1  Header3 6 
-1  SubHeader3 7 
0   Data3  8 
0   Data3a  9 

現在,由於沒有爲「頭2」無數據/「SubHeader2」對時,它需要被刪除。我可以這樣做For ...下一個循環查看「Order」列,並根據序列中當前的位置對+2項進行假設。有沒有辦法與LINQ做到這一點?

編輯:這是一個任意的頭對列表和至少一個或多個數據線。有時數據線丟失。需要刪除丟失數據行的「Header」/「SubHeader」對。

編輯2:這是我刪除不需要的標題對試圖緩解缺乏通過評論和投票工作的批評:

' Sorry for the VB listing. I thought the C# question tag would reach a wider audience 
Class SequentialObject 
    Public Property Underline As Integer 
    Public Property Text As String 
    Public Property Order As Integer 
End Class 

Shared Sub RemoveHeaderPairsWithNoDataLines() 
    Dim sequentialObjectsList As New List(Of SequentialObject) 
    Dim itemsToRemove As New List(Of SequentialObject) 

    sequentialObjectsList.Add(New SequentialObject With {.Underline = -1, .Text = "Header1", .Order = 1}) 
    sequentialObjectsList.Add(New SequentialObject With {.Underline = -1, .Text = "SubHeader1", .Order = 2}) 
    sequentialObjectsList.Add(New SequentialObject With {.Underline = 0, .Text = "Data1", .Order = 3}) 
    sequentialObjectsList.Add(New SequentialObject With {.Underline = -1, .Text = "Header2", .Order = 4}) 
    sequentialObjectsList.Add(New SequentialObject With {.Underline = -1, .Text = "SubHeader2", .Order = 5}) 
    sequentialObjectsList.Add(New SequentialObject With {.Underline = -1, .Text = "Header3", .Order = 6}) 
    sequentialObjectsList.Add(New SequentialObject With {.Underline = -1, .Text = "SubHeader3", .Order = 7}) 
    sequentialObjectsList.Add(New SequentialObject With {.Underline = 0, .Text = "Data3", .Order = 8}) 
    sequentialObjectsList.Add(New SequentialObject With {.Underline = 0, .Text = "Data3a", .Order = 9}) 

    For Each sequentialObject As SequentialObject In sequentialObjectsList 
     ' ignoring here the index out of bounds if current header/subheader are last in the list 
     Dim isUnderlinedTwoLinesAhead As Boolean = (sequentialObjectsList(sequentialObject.Order + 2).Underline = -1) 

     If isUnderlinedTwoLinesAhead Then 
      itemsToRemove.Add(sequentialObject) 
     End If 
    Next 

    For Each itemToRemove As SequentialObject In itemsToRemove 
     sequentialObjectsList.Remove(itemToRemove) 
    Next 

End Sub 
+0

所以在這裏你的規則並不完全清楚。所以基本上,如果有一個條目的文本* fooN *,其中* foo *是一些字符串,* N *是一個int,如果沒有* DataN *,請將其刪除?或者它只是它們在列表中的位置的函數(在這種情況下,它總是2項然後'數據'?如果不是,那麼如何刪除這兩項而不是下兩項? –

+1

另外,是'DataN'是唯一可能丟失的項目?或者您是否需要確保對於任何給定的'N',都存在3個'Text'類型? –

+2

您提到可以使用'for/next'循環執行此操作。如果你先創建了一個工作版本,然後詢問它是否可以轉換爲'Linq',那麼這將會很有幫助,因爲這個問題有點令人困惑 –

回答

1

你可以嘗試這樣的事:

var exludeTextHashSet = new HashSet<string> { "Header2", "SubHeader2 " }; 
var result = records.Where(record=>!excludeHashSet.Contains(record.Text)) 
        .ToList(); 

本質您可以創建要刪除的記錄文本的查找,然後通過驗證將包含在結果列表中的每個記錄的文本值不會包含在中的文本值從初始記錄中過濾出來10。

+0

這是假設他們已經k現在他們想要刪除哪些項目(在這種情況下,這個問題很簡單)。 –

+0

@MattBurland我不認爲他不知道這一點,因爲「Header2」/「SubHeader2」對沒有數據,所以需要刪除它。基於後者,我假設他確實知道這一點。顯然,我可能是錯的。所以我希望OP能給出一些啓示。 – Christos

0

我會使用Where刪除不需要的記錄,然後Select重新從頭開始重新計算正確的順序。

你如何確定這些記錄「沒有數據」?

+3

我認爲他正在尋找的技巧是*如何檢測不需要的物品* –

+0

如果您不刪除不需要的記錄,您可以選擇您想要的記錄。最終結果是一樣的,你只需要對這種情況進行不同的思考。 –

0

我沒有完全理解這個問題,但好像你正在嘗試在一個有序列表上使用LINQ,這取決於列表的順序。 LINQ對此並不好,因爲它適用於無序的IEnumerables。我建議不要使用LINQ。

0

我會建議組織你的代碼更加面向對象。

public class Record 
{ 
    public int Underline { get; set; } 
    public string Text { get; set; } 
    public int Order { get; set; } 
} 

public class RecordGroup 
{ 
    public int Id { get; set; } 
    public Record Header { get; set; } 
    public Record SubHeader { get; set; } 
    public List<Record> DataList { get; set; } 
} 

這樣,檢索包含數據將是微不足道RecordGroup S:

List<RecordGroup> recordGroups = ... 

recordGroups.Where(g => g.DataList.Any()).OrderBy(g => g.Id);