Объедините два (или более) списка в один, на С#.NET.

Можно ли преобразовать два или более списков в один список, в .NET с помощью С#?

Например,

public static List<Product> GetAllProducts(int categoryId){ .... }
.
.
.
var productCollection1 = GetAllProducts(CategoryId1);
var productCollection2 = GetAllProducts(CategoryId2);
var productCollection3 = GetAllProducts(CategoryId3);

Ответ 1

Вы можете использовать методы LINQ Concat и ToList:

var allProducts = productCollection1.Concat(productCollection2)
                                    .Concat(productCollection3)
                                    .ToList();

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

var allProducts = new List<Product>(productCollection1.Count +
                                    productCollection2.Count +
                                    productCollection3.Count);
allProducts.AddRange(productCollection1);
allProducts.AddRange(productCollection2);
allProducts.AddRange(productCollection3);

(AddRange используется для ICollection<T> для эффективности.)

Я бы не стал использовать этот подход, если вам действительно не нужно.

Ответ 2

Предполагая, что вам нужен список, содержащий все продукты для указанных идентификаторов категорий, вы можете обрабатывать ваш запрос в качестве проекции, за которым следует операция сглаживания. Там оператор LINQ, который делает это: SelectMany.

// implicitly List<Product>
var products = new[] { CategoryId1, CategoryId2, CategoryId3 }
                     .SelectMany(id => GetAllProducts(id))
                     .ToList();

В С# 4 вы можете сократить SelectMany до: .SelectMany(GetAllProducts)

Если у вас уже есть списки, представляющие продукты для каждого идентификатора, то вам нужно конкатенация, как указывают другие.

Ответ 3

вы можете комбинировать их с помощью LINQ:

  list = list1.Concat(list2).Concat(list3).ToList();

более традиционный подход использования List.AddRange() может быть более эффективным.

Ответ 4

Вы можете использовать метод расширения Concat:

var result = productCollection1
    .Concat(productCollection2)
    .Concat(productCollection3)
    .ToList();

Ответ 5

Посмотрите List.AddRange, чтобы объединить списки

Ответ 6

list4 = list1.Concat(list2).Concat(list3).ToList();

Ответ 7

Я уже прокомментировал это, но я все еще думаю, что это допустимый вариант, просто проверьте, лучше ли в вашей среде одно решение или другое. В моем конкретном случае использование source.ForEach(p => dest.Add(p)) работает лучше, чем классический AddRange, но я не исследовал причину на низком уровне.

Здесь вы можете увидеть пример кода: https://gist.github.com/mcliment/4690433

Таким образом, опция:

var allProducts = new List<Product>(productCollection1.Count +
                                    productCollection2.Count +
                                    productCollection3.Count);

productCollection1.ForEach(p => allProducts.Add(p));
productCollection2.ForEach(p => allProducts.Add(p));
productCollection3.ForEach(p => allProducts.Add(p));

Попробуйте проверить, работает ли он для вас.

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

Ответ 8

Вам нужно использовать операцию Concat

Ответ 9

В специальном случае: "Все элементы List1 отправляются в новый List2": (например, список строк)

List<string> list2 = new List<string>(list1);

В этом случае list2 генерируется со всеми элементами из списка1.

Ответ 10

// I would make it a little bit more simple

 var products = new List<List<product>> {item1, item2, item3 }.SelectMany(id => id).ToList();

Таким образом, это многомерный список, а .SelectMany() сгладит его в IEnumerable продукта, после чего я буду использовать метод .ToList().