2017-06-02 106 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);