Как объединить два 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, но изменений, которые происходят после этого, не будет. Такая семантика, вероятно, может сбивать с толку; сделав снимок кошки, можно избежать подобных проблем.

Supercat
источник
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);
}
Хассе
источник