如何交叉两个不同的IEnumerable集合

时间:2011-03-29 06:25:21

标签: c# linq generics collections intersection

我认为这个问题之前已被问到,但我还没有能够推断出一个明确的答案。我试图找到最好的方式(或一种方式)来交叉两个完全不同的可相关集合。

A类:

  • int z1
  • int z2
  • int z3
  • string z4

B类:

  • int j5
  • int j6
  • T j7
  • T j8
  • string j9

..我希望List<A>List<B> z2 == j6相交。

可以这样做吗?

4 个答案:

答案 0 :(得分:24)

这个问题没有意义 - 结果类型是什么?必须在两个相同类型的序列上执行交叉。听起来你不太想要两个集合之间的交集,作为基于可能的z2值的第一个序列的过滤器。例如:

HashSet<int> validZ2 = new HashSet<int>(listB.Select(x => x.j6));
var filtered = listA.Where(x => validZ2.Contains(x.z2));

或者像Gabe建议的那样,你想要一个加入。例如:

var query = from a in listA
            join b in listB on a.z2 equals b.j6
            select new { a, b };

这将为您提供两个匹配z2 / j6的列表中的所有值的配对。

答案 1 :(得分:2)

您需要实现自定义相等比较器(请参阅IEqualityComparer<T&gt;接口),将其作为第二个参数传递给Intersect()

答案 2 :(得分:1)

通过使用intersect方法,您可以获得两个枚举之间的公共成员,如此示例所示:

[Test]
public void TestObjectIntersect()
{
    var a = new List<object> { 1, 2, 3, "test", "test2" };
    var b = new List<object> { 4, 5, 1, "test2" };
    var c = a.Intersect(b);
    Console.WriteLine(String.Join(",", c.Select(x => x.ToString()).ToArray()));
}

答案 3 :(得分:0)

class Program
{

    static void Main(string[] args)
    {
        var aList = (from item in Enumerable.Range(1, 10)
                        select new A { Z1 = item, Z2 = item * 2 }).ToList();

        var bList = (from item in Enumerable.Range(10, 100)
                     select new B { J5 = item, J6 = item / 2 }).ToList();

        var intersect = (from a in aList
                         join b in bList
                            on a.Z2 equals b.J6
                         select new { A = a, B = b }).ToList();

        foreach (var item in intersect)
        {
            Console.WriteLine("A:{{{0}}}, B:{{{1}}}", item.A, item.B);
        }
    }
}

public class A
{
    public int Z1 { get; set; }

    public int Z2 { get; set; }

    // other fields and properties

    public override string ToString()
    {
        return string.Format("Z1={0}, Z2={1}", Z1, Z2);
    }
}

public class B
{
    public int J5 { get; set; }

    public int J6 { get; set; }

    // other fields and properties

    public override string ToString()
    {
        return string.Format("J5={0}, J6={1}", J5, J6);
    }
}