Juntando duas listas juntas

Se eu tiver duas listas de tipo string (ou qualquer outro tipo), qual é uma maneira rápida de unir as duas listas?

O pedido deve permanecer o mesmo. As duplicatas devem ser removidas (embora todos os itens em ambos os links sejam exclusivos). Eu não encontrei muito sobre isso quando pesquisei e não queria implementar nenhuma interface .NET para velocidade de entrega.

Você poderia tentar:

List a = new List(); List b = new List(); a.AddRange(b); 

Página do MSDN para AddRange

Isso preserva a ordem das listas, mas não remove quaisquer duplicatas que a Union faria.

Isso muda a lista a . Se você quisesse preservar as listas originais, deveria usar o Concat (como apontado nas outras respostas):

 var newList = a.Concat(b); 

Isso retorna um IEnumerable contanto que a não seja nula.

O caminho com menos sobrecarga de espaço é usar o método de extensão Concat.

 var combined = list1.Concat(list2); 

Cria uma instância de IEnumerable que irá enumerar os elementos de list1 e list2 nessa ordem.

O método da união pode atender às suas necessidades. Você não especificou se o pedido ou as duplicatas eram importantes.

Tome dois IEnumerables e execute uma união como visto aqui:

 int[] ints1 = { 5, 3, 9, 7, 5, 9, 3, 7 }; int[] ints2 = { 8, 3, 6, 4, 4, 9, 1, 0 }; IEnumerable union = ints1.Union(ints2); // yields { 5, 3, 9, 7, 8, 6, 4, 1, 0 } 

Algo assim:

 firstList.AddRange (secondList); 

Ou, você pode usar o método de extensão ‘Union’ definido em System.Linq. Com ‘Union’, você também pode especificar um comparador, que pode ser usado para especificar se um item deve ser unido ou não.

Como isso:

 List one = new List { 1, 2, 3, 4, 5 }; List second=new List { 1, 2, 5, 6 }; var result = one.Union (second, new EqComparer ()); foreach( int x in result ) { Console.WriteLine (x); } Console.ReadLine (); #region IEqualityComparer Members public class EqComparer : IEqualityComparer { public bool Equals( int x, int y ) { return x == y; } public int GetHashCode( int obj ) { return obj.GetHashCode (); } } #endregion 
 targetList = list1.Concat(list2).ToList(); 

Está funcionando bem, eu acho que sim. Como dito anteriormente, o Concat retorna uma nova sequência e, ao converter o resultado para List, faz o trabalho perfeitamente. Conversões implícitas podem falhar algumas vezes ao usar o método AddRange.

Se algum item existir em ambas as listas, você poderá usar

 var all = list1.Concat(list2).Concat(list3) ... Concat(listN).Distinct().ToList(); 

Desde que sejam do mesmo tipo, é muito simples com o AddRange:

 list2.AddRange(list1); 

O método AddRange

 aList.AddRange( anotherList ); 
 var bigList = new List { 1, 2, 3 } .Concat(new List { 4, 5, 6 }) .ToList(); /// yields { 1, 2, 3, 4, 5, 6 } 
 List list1 = new List(); list1.Add("dot"); list1.Add("net"); List list2 = new List(); list2.Add("pearls"); list2.Add("!"); var result = list1.Concat(list2); 

um caminho: List.AddRange (), dependendo dos tipos?

Veja este link

 public class ProductA { public string Name { get; set; } public int Code { get; set; } } public class ProductComparer : IEqualityComparer { public bool Equals(ProductA x, ProductA y) { //Check whether the objects are the same object. if (Object.ReferenceEquals(x, y)) return true; //Check whether the products' properties are equal. return x != null && y != null && x.Code.Equals(y.Code) && x.Name.Equals(y.Name); } public int GetHashCode(ProductA obj) { //Get hash code for the Name field if it is not null. int hashProductName = obj.Name == null ? 0 : obj.Name.GetHashCode(); //Get hash code for the Code field. int hashProductCode = obj.Code.GetHashCode(); //Calculate the hash code for the product. return hashProductName ^ hashProductCode; } } ProductA[] store1 = { new ProductA { Name = "apple", Code = 9 }, new ProductA { Name = "orange", Code = 4 } }; ProductA[] store2 = { new ProductA { Name = "apple", Code = 9 }, new ProductA { Name = "lemon", Code = 12 } }; 

// Obtenha os produtos das duas matrizes // excluindo duplicatas.

 IEnumerable union = store1.Union(store2); foreach (var product in union) Console.WriteLine(product.Name + " " + product.Code); /* This code produces the following output: apple 9 orange 4 lemon 12 */ 

Eu só queria testar como Union funciona com o comparador padrão em collections sobrepostas de objects de tipo de referência.

Meu objective é:

 class MyInt { public int val; public override string ToString() { return val.ToString(); } } 

Meu código de teste é:

 MyInt[] myInts1 = new MyInt[10]; MyInt[] myInts2 = new MyInt[10]; int overlapFrom = 4; Console.WriteLine("overlapFrom: {0}", overlapFrom); Action, string> printMyInts = (myInts, myIntsName) => Console.WriteLine("{2} ({0}): {1}", myInts.Count(), string.Join(" ", myInts), myIntsName); for (int i = 0; i < myInts1.Length; i++) myInts1[i] = new MyInt { val = i }; printMyInts(myInts1, nameof(myInts1)); int j = 0; for (; j + overlapFrom < myInts1.Length; j++) myInts2[j] = myInts1[j + overlapFrom]; for (; j < myInts2.Length; j++) myInts2[j] = new MyInt { val = j + overlapFrom }; printMyInts(myInts2, nameof(myInts2)); IEnumerable myUnion = myInts1.Union(myInts2); printMyInts(myUnion, nameof(myUnion)); for (int i = 0; i < myInts2.Length; i++) myInts2[i].val += 10; printMyInts(myInts2, nameof(myInts2)); printMyInts(myUnion, nameof(myUnion)); for (int i = 0; i < myInts1.Length; i++) myInts1[i].val = i; printMyInts(myInts1, nameof(myInts1)); printMyInts(myUnion, nameof(myUnion)); 

A saída é:

 overlapFrom: 4 myInts1 (10): 0 1 2 3 4 5 6 7 8 9 myInts2 (10): 4 5 6 7 8 9 10 11 12 13 myUnion (14): 0 1 2 3 4 5 6 7 8 9 10 11 12 13 myInts2 (10): 14 15 16 17 18 19 20 21 22 23 myUnion (14): 0 1 2 3 14 15 16 17 18 19 20 21 22 23 myInts1 (10): 0 1 2 3 4 5 6 7 8 9 myUnion (14): 0 1 2 3 4 5 6 7 8 9 20 21 22 23 

Então, tudo funciona bem.

As duas opções que uso são:

 list1.AddRange(list2); 

ou

 list1.Concat(list2); 

No entanto, notei que eu usei isso quando usando o método AddRange com uma function recursiva, que chama-se muitas vezes eu tenho um SystemOutOfMemoryException porque o número máximo de dimensões foi atingido.

(Mensagem Google Traduzido)
As dimensões da matriz excederam o intervalo suportado.

O uso do Concat resolveu esse problema.

Um modo, eu não vi mencionado que pode ser um pouco mais robusto, particularmente se você quisesse alterar cada elemento de alguma forma (por exemplo, você queria .Trim() todos os elementos.

 List a = new List(); List b = new List(); // ... b.ForEach(x=>a.Add(x.Trim()));