我有一个连续的记录列表。简化结构如下:
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
现在,由于“Header2”/“SubHeader2”对没有数据,因此需要将其删除。我可以执行For ... Next循环查看“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 :(得分:1)
您可以尝试这样的事情:
var exludeTextHashSet = new HashSet<string> { "Header2", "SubHeader2 " };
var result = records.Where(record=>!excludeHashSet.Contains(record.Text))
.ToList();
基本上,您为要删除的记录的文本创建查找,然后通过验证将包含在结果列表中的每个记录都没有文本值来从初始记录中筛选出来。包含在exludeTextHashSet
。
答案 1 :(得分:0)
我会使用Where
删除不需要的记录,然后使用Select
从头开始重新计算正确的顺序。
您如何确定没有数据&#34;那些记录?
答案 2 :(得分:0)
我不完全理解这个问题,但似乎你试图以一种取决于列表顺序的方式在有序列表上使用LINQ。 LINQ对此并不好,因为它适用于无序的IEnumerables。我建议不要使用LINQ。
答案 3 :(得分: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
将是微不足道的:
List<RecordGroup> recordGroups = ...
recordGroups.Where(g => g.DataList.Any()).OrderBy(g => g.Id);