Как динамически добавлять элементы List <T>в IEnumerable <T> - PullRequest
1 голос
/ 07 ноября 2019

Код

public static void Main()
{
    List<int> list1 = new List<int> {1, 2, 3, 4, 5, 6 };
    List<int> list2 = new List<int> {1, 2, 3 };
    List<int> list3 = new List<int> {1, 2 };
    var lists = new IEnumerable<int>[] { list1, list2, list3 };
    var commons = GetCommonItems(lists);
    Console.WriteLine("Common integers:");
    foreach (var c in commons)
        Console.WriteLine(c);
}

static IEnumerable<T> GetCommonItems<T>(IEnumerable<T>[] lists)
{
    HashSet<T> hs = new HashSet<T>(lists.First());
    for (int i = 1; i < lists.Length; i++)
        hs.IntersectWith(lists[i]);
    return hs;
}

Что касается примера, я показал "list1" "list2" "list3", но у меня может быть более 50 списков, которые генерируют каждый список с использованиемдля каждой петли. Как можно программно добавить каждый «список» в IEnumerable списки для сравнения данных каждого списка?

Я пробовал много способов, таких как преобразование в список, Add, Append, Concat, но ничего не получалось.

Есть ли другой лучший способ сравнить число списков N?

Вывод кода: 1 2

Ответы [ 3 ]

1 голос
/ 07 ноября 2019

Вы можете создать список списков и динамически добавлять списки в этот список. Примерно так:

var lists = new List<List<int>>();
lists.Add(new List<int> {1, 2, 3, 4, 5, 6 });
lists.Add(new List<int> {1, 2, 3 });
lists.Add(new List<int> {1, 2 });

foreach (var list in listSources)
    lists.Add(list);

var commons = GetCommonItems(lists);

Чтобы найти пересечения, вы можете использовать это решение, например: Пересечение нескольких списков с помощью IEnumerable.Intersect () (на самом деле похоже, это то, что вы уже используете).

Также обязательно измените подпись метода GetCommonItems:

static IEnumerable<T> GetCommonItems<T>(List<List<T>> lists)
0 голосов
/ 07 ноября 2019

Что вы можете сделать, это разрешить методу GetCommonItems принимать переменное количество параметров, используя ключевое слово params . Таким образом, вам не нужно создавать новую коллекцию списков.

Однако само собой разумеется, что если количество списков в вашем источнике также является переменным, это может быть сложнее использовать.

Я также изменил метод GetCommonItems, чтобы он работал как код из https://stackoverflow.com/a/1676684/9945524

public static void Main()
{
    List<int> list1 = new List<int> { 1, 2, 3, 4, 5, 6 };
    List<int> list2 = new List<int> { 1, 2, 3 };
    List<int> list3 = new List<int> { 1, 2 };

    var commons = GetCommonItems(list1, list2, list3); // pass the lists here

    Console.WriteLine("Common integers:");
    foreach (var c in commons)
        Console.WriteLine(c);
}

static IEnumerable<T> GetCommonItems<T>(params List<T>[] lists)
{
    return lists.Skip(1).Aggregate(
        new HashSet<T>(lists.First()),
        (hs, lst) =>
        {
            hs.IntersectWith(lst);
            return hs;
        }
    );
}

Альтернативное решение с использованием существующего метода Main.

РЕДАКТИРОВАТЬ:изменил тип lists на List<List<int>> согласно комментарию в этом ответе.

public static void Main()
{
    List<int> list1 = new List<int> { 1, 2, 3, 4, 5, 6 };
    List<int> list2 = new List<int> { 1, 2, 3 };
    List<int> list3 = new List<int> { 1, 2 };
    var lists = new List<List<int>> { list1, list2, list3 };
    var commons = GetCommonItems(lists);
    Console.WriteLine("Common integers:");
    foreach (var c in commons)
        Console.WriteLine(c);
}

static IEnumerable<T> GetCommonItems<T>(List<List<T>> lists)
{
    return lists.Skip(1).Aggregate(
        new HashSet<T>(lists.First()),
        (hs, lst) =>
        {
            hs.IntersectWith(lst);
            return hs;
        }
    );
}
0 голосов
/ 07 ноября 2019
  1. IEnumerable является неизменным, поэтому вы всегда должны возвращать реализацию IEnumerable в зависимости от ваших потребностей.
  2. Если я правильно понимаю, вы хотите получить общие элементы из N списков. Для этого я бы использовал LINQ.

Мое предложение: 1. составить один список, содержащий все элементы. =>

var allElements = new List<int>();
  var lists = new List<List<int>>();
foreach (list in lists)
    allElements.AddRange(list);
Возьмите предметы, которые повторяются

allElements.GroupBy(x => x).Where(x => x.Count() > 1).Select(x => x).ToList();

...