【问题标题】:How to intersect two different IEnumerable collections如何相交两个不同的 IEnumerable 集合
【发布时间】:2011-07-25 00:47:09
【问题描述】:

我认为这个问题之前已经被问过,但我无法推断出明确的答案。我正在尝试找到与两个完全不同的可枚举集合相交的最佳方式(或方法)。

A 类:

  • int z1
  • int z2
  • int z3
  • 字符串 z4

B 类:

  • int j5
  • int j6
  • T j7
  • T j8
  • 字符串 j9

..我想在z2 == j6 上将List<A>List<B> 相交。

这个可以吗?

【问题讨论】:

标签: c# linq generics collections intersection


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    通过使用 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()));
    }
    

    【讨论】:

    • 我不这么认为。在这种情况下,就像在大多数情况下编码一样,多种解决方案都可以满足要求。这一切都取决于提出要求的人想要达到的目标。不过,我认为您的回答更有意义。
    • Jon 的意思是你有两个 List&lt;object&gt;,而 OP 想要将 List&lt;A&gt;List&lt;B&gt;“相交”(其中 A 和 B 是不同的类型)。
    • 你和乔恩都是对的。我错过了格兰特的最后一次编辑,这使得这一点更加清晰。我很抱歉。
    【解决方案3】:

    这个问题没有真正的意义——结果类型是什么?必须在相同类型的两个序列上执行交叉。听起来您并不太想要两组之间的交集,而是基于 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 匹配的所有值对。

    【讨论】:

    • 我认为 OP 实际上可能想要加入。
    • @Gabe:说实话,这很难说。这是可能的 - 我会编辑以防万一。不过,这并不是真正的十字路口……
    • 我的猜测是 OP 无法理解其他答案,因为他们使用了错误的术语。正如您所说,交集对不同的数据类型没有意义。但是,如果您将“交集”重新解释为“查找匹配值”,则“加入”也符合定义。由于连接对于不同的数据类型确实有意义,我认为这更有可能是 OP 想要的。
    • 谢谢你..你是对的。我实际上想过滤第一个序列的结果。谢谢 - 使用加入!
    【解决方案4】:
    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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      • 1970-01-01
      • 2012-05-05
      • 1970-01-01
      • 2011-04-29
      • 1970-01-01
      相关资源
      最近更新 更多