在两个LINQ语句中使用Union并去除重复项

3

我在互联网上寻找了一段时间,但却没有找到我真正需要的内容。我的问题是我有两个linq语句,我打算将它们合并成一个列表集合,但我想要删除那些重复的值。具体来说,以下是一个场景:

query 1 = "this is a test","Yes", "This is a remark"
          "this is a test2","No", "This is the second remark"

query 2 = "this is a test","",""
          "this is a test2","",""
          "this is a test3","",""
          "this is a test4","",""

现在我希望发生的事情是这样的:
          "this is a test","Yes", "This is a remark"
          "this is a test2","No", "This is the second remark",
          "this is a test3","",""
          "this is a test4","",""

我该如何在LINQ中实现这个功能?提前感谢您!

你尝试过 .Distinct() 吗? - Mirco Ellmann
是的先生..我试过了,但没有效果.. - Clyde
查询的返回结果是什么? - Chamika Sandamal
"这是一个测试", "是的", "这是一条备注" "这是第二个测试", "不", "这是第二条备注" "这是第三个测试", "", "" "这是第四个测试", "", "" - Clyde
3个回答

4
您可以使用以下查询:
var result = from item in query2
             let match = query1.SingleOrDefault (e => e[0] == item[0])
             select match ?? item;

这将遍历query2,并对于每个项目,它使用SingleOrDefaultquery1中查找元素匹配的第一个项目或null。然后,如果match不是null,则selectquery1返回匹配项,否则返回query2的当前项。
另一种可能更快的方法是创建适当的IEqualityComparer并使用Union,如下所示:
class FirstElementComparer : IEqualityComparer<string[]>
{
    //TODO error checking
    public bool Equals(string[] a, string[] b)
    {       
        return a[0].Equals(b[0]);
    }

    public Int32 GetHashCode(string[] obj)
    {
        return obj[0].GetHashCode();
    }
}

并且像这样使用它:

void Main()
{
    string[][] query1 = {new [] {"this is a test","Yes", "This is a remark"},
                         new [] {"this is a test2","No", "This is the second remark"}};

    string[][] query2 = {new [] {"this is a test","",""},
                         new [] {"this is a test2","",""},
                         new [] {"this is a test3","",""},
                         new [] {"this is a test4","",""}};

    query1.Union(query2, new FirstElementComparer()).Dump();                         
}
EqualityComparerUnion 用于比较 query1 中的元素和 query2 中的元素。它是通过仅比较每个数组中的第一个项来实现的。
结果:

enter image description here


您好!问题已经解决了。能否请您解释一下这个呢,谢谢!我是LINQ的新手。 - Clyde
@VincentClyde 我添加了一些解释。 - sloth
当query1中存在query2不存在的项目时,将无法正常工作。 - Serge
@Serge 的解决方案第一种是正确的,但OP在一个已删除的评论中说这并非总是如此。 - sloth
@Dominic,“Dump”是什么?它是System.Linq的一部分吗? - Serge
1
@Serge 不是的,这是由linqpad提供的扩展方法,可以打印任何对象,就像你在图片中看到的那样。如果你不知道linqpad,真的应该试试 :-) - sloth

3

Something like this...

query1.Union(query2).GroupBy(q => q[0]).Select(grp => grp.FirstOrDefault());

(未测试)


1
应该使用 Select 而不是 SelectMany,否则这个代码应该可以工作。另外,你可以使用 First 而不是 FirstOrDefault,因为每个组至少有一个元素,所以使用 ...OrDefault 变体是没有意义的。由于集合的元素不匹配,使用 Default 比较器,Union 在这里等同于 Concat,可能会稍微慢一点。 - sloth
是的,我刚刚注意到了SelectMany。至于FirstOrDefault,你说得完全正确,但对我来说使用它已经成为一种习惯。 ;) - Serge

-2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接