Как объединить два IEnumerable <T> в новый IEnumerable <T>?


201

У меня есть два экземпляра IEnumerable<T>(с одинаковыми T). Я хочу новый экземпляр, IEnumerable<T>который является объединением обоих.

Есть ли встроенный метод в .Net, чтобы сделать это, или я должен написать это сам?


9
Вы можете добавить в закладки code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b .
C-Pound Guru

Ответы:


332

Да, LINQ to Objects поддерживает это с Enumerable.Concat:

var together = first.Concat(second);

NB: Если бы вы были firstили secondбыли нулем, вы бы получили ArgumentNullException. Чтобы избежать этого и обрабатывать пустые значения как пустой набор, используйте оператор объединения нулей следующим образом:

var together = (first ?? Enumerable.Empty<string>()).Concat(second ?? Enumerable.Empty<string>()); //amending `<string>` to the appropriate type

1
Я всегда забываю искать методы расширения, TX.
Сэмюэль Россиль

10
@SamuelRossille Также не забывайте, что названия действий, которые вы хотите выполнить, скорее всего близки, если не точно названы, что вы ищете. Всегда просматривайте IntelliSense, вы узнаете много нового.
Адам Хоулдсворт

3
Разве плохо делать second = first.Concat (second)? у нас будут проблемы с параллелизмом?
user2934433

4
@ user2934433: Нет, это совершенно нормально.
Джон Скит

2
Просто быстрая заметка. Требуется импортировать using System.Linq пространство имен в верхней части файла кода, чтобы увидеть нужный метод расширения в intellisense IDE.
RBT

19

ConcatМетод возвращает объект , который реализует IEnumerable<T>путем возврата объекта (назовем его Cat) , чей перечислитель будет пытаться использовать два переданное перечислимых элементов (назовем их А и В) в определенной последовательности. Если переданные перечислимые числа представляют последовательности, которые не изменятся в течение срока службы Cat и могут быть прочитаны без побочных эффектов, тогда Cat может использоваться напрямую. В противном случае, это может быть идея хорошо , чтобы позвонить ToList()на Catи использовать полученную List<T>(который будет представлять собой снимок содержимого А и В).

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


7

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

public void Linq94() 
{ 
    int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 
    int[] numbersB = { 1, 3, 5, 7, 8 }; 

    var allNumbers = numbersA.Concat(numbersB); 

    Console.WriteLine("All numbers from both arrays:"); 
    foreach (var n in allNumbers) 
    { 
        Console.WriteLine(n); 
    } 
}

0
// The answer that I was looking for when searching
public void Answer()
{
    IEnumerable<YourClass> first = this.GetFirstIEnumerableList();
    // Assign to empty list so we can use later
    IEnumerable<YourClass> second = new List<YourClass>();

    if (IwantToUseSecondList)
    {
        second = this.GetSecondIEnumerableList();  
    }
    IEnumerable<SchemapassgruppData> concatedList = first.Concat(second);
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.