【问题标题】:Find the intersection of two lists in linq?在linq中找到两个列表的交集?
【发布时间】:2011-02-21 11:53:21
【问题描述】:

我有 int A,B 的列表。我喜欢在 linq 中执行以下步骤

list<int> c = new List<int>();

for (int i = 0; i < a.count; i++)
{
    for (int j = 0; j < b.count; j++)
    {
        if (a[i] == b[j])
        {
            c.add(a[i]);
        }
    }
}

如果它的 a 和 b 是 object ,我需要像这种方式检查特定属性并添加列表,如果它等于我如何在 linq 中执行此操作?

【问题讨论】:

  • 如果 a 或 b 中有重复项,此代码将返回 c 中的重复项。例如 a = {1,2,2,3} 和 b = {2,2,4,6} 将给出 c = {2,2,2,2}。这是您想要的还是您的列表是独一无二的,所以它并不重要?我问只是因为明显的 linq 答案会给出 c={2,2} 因为那是列表的交集。
  • @Femaref:真的吗?喔好吧。至少我的观点仍然成立。我仍然不擅长这样的 linq 东西。 :)
  • 这不仅限于 LINQ。 This 可能适合您阅读。
  • 标题具有误导性。对于找到此页面并真正想比较两个可枚举项是否相等的任何人,Linq 有一个名为 SequenceEqual 的方法。

标签: c# linq


【解决方案1】:

您可以使用Intersect 方法:

var c = a.Intersect(b);

这将返回 a 和 b 中的所有值。但是,不考虑项目在列表中的位置。

【讨论】:

  • 为遇到此问题的其他人保存 google,相反的 LINQ 方法是“Except”。
  • OP 的代码也没有考虑位置,所以这不是问题 - 但是 OP 的代码做了一些非常不寻常的事情,Intersect 没有:对于每个不同的元素 e 存在于ab 中,e 被添加到c n,其中 n = [ea 中出现的次数] * [eb 中出现的次数]。这根本不是一个相交,但也许 OP 打算进行一个相交并且只是错误地实现了它?
【解决方案2】:

你可以使用Intersect:

var a = new List<int>();
var b = new List<int>();

var c = a.Intersect(b);

【讨论】:

【解决方案3】:

生成一个列表c,其中包含两个列表ab 中存在的所有元素:

List<int> c = a.Intersect(b).ToList();

【讨论】:

    【解决方案4】:

    这是我的交集版本:

    var a = new List<int>();
    var b = new List<int>();
    
    // intersection
    var c = a.Where(x => b.Any(y => x == y)).ToList();
    

    【讨论】:

      【解决方案5】:

      您的代码的 LINQ 等效项是:

      var c = from i in Enumerable.Range(0, a.Count)
              from j in Enumerable.Range(0, b.Count)
              where a[i] == b[j]
              select a[i];
      
      var cList = c.ToList();
      

      但这样做更好:

      var c = from aItem in a 
              join bItem in b on aItem equals bItem
              select aItem;
      
      var cList = c.ToList();
      

      但这不会过滤重复项。要完全过滤重复项,您可以:

      var cList = a.Intersect(b).ToList();
      

      如果您希望重复出现的次数与它们在 b 中一样多,例如:

      var aSet = new HashSet<int>(a);
      var cList = b.Where(aSet.Contains)
                   .ToList(); 
      

      【讨论】:

        【解决方案6】:

        正如 Chris 在他对原始问题的评论中提到的那样,提供的示例代码将返回列表 c 中的重复项(有关详细信息,请参阅他的评论)。 Intersect 只会返回不同的值。要复制原始示例代码的行为,请尝试以下操作:

        var c = (from value in a
                 where b.Contains(a)
                 select a);
        

        【讨论】:

        • 那会是一样的吗?如果它在 b 中两次,那将不会返回两次中的值吗?
        • 嗯...不确定,但很好。我需要试验一下才能找到答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-06-15
        • 2010-10-13
        • 2013-10-12
        • 2021-03-18
        • 2013-08-07
        • 1970-01-01
        • 2021-01-17
        相关资源
        最近更新 更多