Como concatenar dois IEnumerable <T> em um novo IEnumerable <T>?

201

Eu tenho duas instâncias de IEnumerable<T>(com o mesmo T). Eu quero uma nova instância da IEnumerable<T>qual é a concatenação de ambos.

Existe um método embutido no .Net para fazer isso ou eu mesmo tenho que escrever?

Samuel Rossille
fonte

Respostas:

332

Sim, o LINQ to Objects suporta isso com Enumerable.Concat:

var together = first.Concat(second);

NB: Se for firstou secondfor nulo, você receberá a ArgumentNullException. Para evitar isso e tratar nulos como faria com um conjunto vazio, use o operador coalescente nulo da seguinte maneira:

var together = (first ?? Enumerable.Empty<string>()).Concat(second ?? Enumerable.Empty<string>()); //amending `<string>` to the appropriate type
Jon Skeet
fonte
1
Eu sempre esqueço de procurar métodos de extensão, tx.
Samuel Rossille
10
@SamuelRossille Também não se esqueça de que os nomes das ações que você deseja executar provavelmente estão próximos, se não exatamente chamados do que você está procurando. Sempre navegue no IntelliSense, você aprende muito.
Adam Houldsworth 31/01
3
É ruim fazer o segundo = primeiro.Concat (segundo)? teremos problemas de concorrência?
User2934433
4
@ user2934433: Não, isso é absolutamente bom.
Jon Skeet
2
Apenas uma nota rápida. É necessário importar o using System.Linq namespace na parte superior do arquivo de código para ver o método de extensão desejado no IDE intellisense.
RBT 02/02
19

O Concatmétodo retornará um objeto implementado IEnumerable<T>retornando um objeto (chamado Cat), cujo enumerador tentará usar os dois itens enumeráveis ​​passados ​​(os chamados A e B) em sequência. Se os enumeráveis ​​passados ​​representam sequências que não serão alteradas durante a vida útil do gato e que podem ser lidas sem efeitos colaterais, o gato poderá ser usado diretamente. Caso contrário, pode ser uma boa idéia para chamar ToList()on Cate usar o resultado List<T>(o que representará um instantâneo do conteúdo de A e B).

Alguns enumeráveis ​​tiram um instantâneo quando a enumeração começa e retornam dados desse instantâneo se a coleção for modificada durante a enumeração. Se B for um enumerável, qualquer alteração em B que ocorra antes do final de A de Cat será exibida na enumeração de Cat, mas as alterações que ocorrerem depois disso não serão. Essa semântica provavelmente pode ser confusa; tirar uma foto instantânea do Cat pode evitar esses problemas.

supercat
fonte
7

Você pode usar o código abaixo para sua solução: -

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); 
    } 
}
Jay Shukla
fonte
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);
}
Hasse
fonte