【问题标题】:union in two linq statements and remove the duplicate在两个 linq 语句中联合并删除重复项
【发布时间】:2013-05-08 18:04:26
【问题描述】:

我在互联网上搜索了一段时间,但找不到我真正需要的东西。我的问题是我有两个 linq 语句,我计划将它们放在 UNION 中,以便将它们合并到一组列表中,但我想删除那些重复的值。具体来说,这里是一个场景:

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() 吗?
  • 是的先生..试过了但没有效果..
  • 查询的返回结果是什么?
  • "this is a test","Yes", "This is a remark" "this is a test2","No", "This is the second remark", "this is a test3" ,"","" "这是一个测试4","","" 这是我所期待的,先生

标签: c# linq


【解决方案1】:

您可以使用以下查询:

var result = from item in query2
             let match = query1.SingleOrDefault (e => e[0] == item[0])
             select match ?? item;

这将遍历query2,并且对于每个项目,它使用SingleOrDefaultquery1 中查找项目的第一个元素匹配的项目,或null。然后,select 会产生来自 query1 的名为 match 的项目,如果它不是 null,或者是 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();                         
}

Union 使用EqualityComparerquery1 中的元素与query2 中的元素进行比较。它仅通过比较每个数组中的第一项来实现。


结果:

【讨论】:

  • 您好先生!这已经解决了问题.. 先生,您能解释一下吗?非常感谢!我是 linq 的新手
  • @VincentClyde 我添加了一些解释。
  • 当 query1 中有项目在 query2 中不存在时将不起作用。
  • @Serge True 对于第一个解决方案,但 OP 表示情况一直如此(在已删除的评论中)。
  • @Serge 不,它是linqpad 提供的扩展方法,用于打印任何对象,如图所示。如果你不知道 linqpad,你真的应该试一试 :-)
【解决方案2】:

这样的……

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

(未测试)

【讨论】:

  • 应该是Select 而不是SelectMany,否则应该可以。您也可以使用First 而不是FirstOrDefault,因为每个组至少有一个元素,所以使用...OrDefault 变体是没有意义的。由于使用Default-比较器无法匹配集合的元素,因此Union 在这里相当于Concat,可能会慢一点(非常慢)。
  • 是的,我刚刚注意到 SelectMany。至于FirstOrDefault,你说得完全正确,但我使用它是一种习惯。 ;)
【解决方案3】:

尝试使用 .Distinct()。有关详细信息,请参阅下面的链接:

LINQ: Distinct values

【讨论】:

    猜你喜欢
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 2021-06-02
    • 2017-06-22
    相关资源
    最近更新 更多