使用LINQ删除'Multicolumn'列表的重复条目

时间:2013-07-26 22:14:47

标签: .net regex vb.net linq duplicate-removal

我有2个相同用户定义类型的列表。每个包括:ID,TimesTested,varA,varB。

需要加入列表,然后将其保存到本地文件中。需要删除重复的条目。

问题是我不能只搜索ID并检查它是否已存在,因为我总是需要保留“TimesTested”具有更高值的条目。

我真的不想通过两个列表循环并返回并手动检查值。所以我在考虑LINQ。

如果我给出了以下内容,是否可以执行以下操作:

4, 16, X, Y
4, 19, X, Y

只保留第二行? (使用LINQ,或以其他'智能'方式)

如果是的话,请你解释一下怎么样?


奇怪的是,当我第一次从本地文件加载值时它会起作用。 也是第一次保存似乎工作顺利...但是一旦我尝试第二次写入文件列表..我得到以下错误:

Unable to cast object of type "WhereSelectEnumerableIterator`2[System.Linq.IGrouping`2[System.Int32,mcq_gui.clsEvaluation+History+EvaluationQuestionData],mcq_gui.clsEvaluation+History+EvaluationQuestionData]" to type Typ "System.Collections.Generic.List`1[mcq_gui.clsEvaluation+History+EvaluationQuestionData]"

这是我正在使用的代码:

Friend Shared Function GetNewerEvalQs(list1 As List(Of EvaluationQuestionData), list2 As List(Of EvaluationQuestionData)) As List(Of EvaluationQuestionData)
        Dim uniques As New List(Of EvaluationQuestionData)
        Try
            If list1.Count > 0 And list2.Count > 0 Then
                uniques = list1.Concat(list2).GroupBy(Function(t) t.ID).[Select](Function(g) g.OrderByDescending(Function(t) t.TimesTested).First())
            Else
                If list1.Count > 0 Then
                    Return list1
                ElseIf list2.Count > 0 Then
                    Return list2
                Else
                    Return Nothing
                End If
            End If

            Return uniques
        Catch ex As Exception
            Debug.Print(ex.Message)
            Return Nothing
        End Try
    End Function

1 个答案:

答案 0 :(得分:0)

单向,使用Enumerable.GroupBy,然后根据TimesTested选择最高。

var uniques = list1.Concat(list2)
    .GroupBy(t => t.ID)
    .Select(g => g.OrderByDescending(t => t.TimesTested).First());

编辑 ...或者在VB.NET中(抱歉,我没有先看到标记)并使用您的方法:

Friend Shared Function GetNewerEvalQs(list1 As List(Of EvaluationQuestionData), list2 As List(Of EvaluationQuestionData)) As List(Of EvaluationQuestionData)
    list1 = If(list1 Is Nothing, New List(Of EvaluationQuestionData), list1)
    list2 = If(list2 Is Nothing, New List(Of EvaluationQuestionData), list2)
    If Math.Max(list1.Count, list2.Count) = 0 Then Throw New ArgumentException("One of both lists must contain data")

    Dim newUniqueData = list1.Concat(list2).
        OrderByDescending(Function(eqd) eqd.TimeTested).
        GroupBy(Function(eqd) eqd.ID).
        Select(Function(g) g.First()).
        ToList()
    Return newUniqueData
End Function