Использование LINQ для объединения [n] коллекций и поиска совпадений - PullRequest
0 голосов
/ 21 февраля 2011

Используя LINQ, я могу найти совпадающие элементы между двумя коллекциями, например:

        var alpha = new List<int>() { 1, 2, 3, 4, 5 };
        var beta = new List<int>() { 1, 3, 5 };

        return (from a in alpha
                join b in beta on a equals b
                select a);

Я могу увеличить это до трех коллекций, например так:

        var alpha = new List<int>() { 1, 2, 3, 4, 5 };
        var beta = new List<int>() { 1, 3, 5 };
        var gamma = new List<int>() { 3 };

        return (from a in alpha
                join b in beta on a equals b
                join g in gamma on a equals g
                select a);

Но как я могу построить запрос LINQ, который будет возвращать совпадения между N количеством коллекций?

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

Ответы [ 2 ]

3 голосов
/ 21 февраля 2011

Нет необходимости повторять - вы можете просто повторить. Тем не менее, вам может быть лучше создать набор и пересекать , что каждый раз:

List<List<int>> collections = ...;

HashSet<int> values = new HashSet<int>(collections[0]);
foreach (var collection in collections.Skip(1)) // Already done the first
{
    values.IntersectWith(collection);
}

(Как и BrokenGlass, я предполагаю, что у вас есть значения distint, и что вы действительно просто хотите найти значения, которые есть во всех коллекциях.)

Если вы предпочитаете неизменный и ленивый подход, вы можете использовать:

List<List<int>> collections = ...;

IEnumerable<int> values = collections[0];
foreach (var collection in collections.Skip(1)) // Already done the first
{
    values = values.Intersect(collection);
}
1 голос
/ 21 февраля 2011

Если у вас есть только уникальные значения, вы можете использовать Пересечение:

var result = alpha.Intersect(beta).Intersect(gamma).ToList();

Если вам нужно сохранить несколько неуникальных значений, вы можете просто исключить непересекающиеся элементы из исходной коллекции в качестве дополнительного шага.:

alpha = alpha.Where(x => result.Contains(x)).ToList();

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

IEnumerable<List<int>> collections = new [] { alpha, beta, gamma };
IEnumerable<int> result = collections.First();
foreach (var item in collections.Skip(1))
{
    result = result.Intersect(item);
}
result = result.ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...