Как пересечь две разные коллекции IEnumerable - PullRequest
6 голосов
/ 29 марта 2011

Я думаю, что этот вопрос уже задавался, но я не смог дать четкий ответ. Я пытаюсь найти лучший способ (или способ) пересечь две совершенно разные неисчислимые коллекции.

класс A:

  • int z1
  • int z2
  • int z3
  • строка z4

класс B:

  • int j5
  • int j6
  • Т j7
  • Т j8
  • Строка J9

.. Я хочу пересечь List<A> с List<B> на z2 == j6.

это можно сделать?

Ответы [ 4 ]

25 голосов
/ 29 марта 2011

Вопрос на самом деле не имеет смысла - каким будет тип результата? Пересечения должны выполняться на двух последовательностях одного типа. Звучит так, будто вы не так сильно хотите пересечения между двумя наборами, как фильтр первой последовательности, основанный на возможных значениях z2. Например:

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

Или, возможно, как предполагает Гейб, вы хотите присоединиться. Например:

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

Это даст вам все пары значений из двух списков, которые совпадают на z2 / j6.

2 голосов
/ 29 марта 2011

Вам необходимо реализовать собственный компаратор равенства (см. IEqualityComparer<T> интерфейс), чтобы передать его в качестве второго аргумента Intersect().

1 голос
/ 29 марта 2011

Используя метод пересечения, вы можете получить общие члены между двумя перечисляемыми значениями, как показано в этом примере:

[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()));
}
0 голосов
/ 29 марта 2011
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);
    }
}
...