c#

c# - Uniendo dos listas juntas



(15)

Algo como esto:

firstList.AddRange (secondList);

O bien, puede usar el método de extensión ''Unión'' que se define en System.Linq. Con ''Unión'', también puede especificar un comparador, que se puede usar para especificar si un elemento debe ser unido o no.

Me gusta esto:

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

Si tengo dos listas de tipo cadena (o cualquier otro tipo), ¿cuál es una forma rápida de unir las dos listas?

El orden debe permanecer igual. Los duplicados deben eliminarse (aunque todos los elementos de ambos enlaces son únicos). No encontré mucho en esto al buscar en Google y no quería implementar ninguna interfaz .NET para la velocidad de entrega.


De una manera, no he visto mencionado que puede ser un poco más robusto, especialmente si quisieras alterar cada elemento de alguna manera (por ejemplo, querías .Trim() todos los elementos.

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


El método AddRange

var bigList = new List<int> { 1, 2, 3 } .Concat(new List<int> { 4, 5, 6 }) .ToList(); /// yields { 1, 2, 3, 4, 5, 6 }


El método de la Union podría abordar sus necesidades. No especificó si el orden o los duplicados eran importantes.

Tome dos IEnumerables y realice una unión como se ve aquí:

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


La forma con la menor sobrecarga de espacio es utilizar el método de extensión Concat.

var combined = list1.Concat(list2);

Crea una instancia de IEnumerable<T> que enumerará los elementos de list1 y list2 en ese orden.


Las dos opciones que uso son:

list1.AddRange(list2);

o

list1.Concat(list2);

Sin embargo, noté que al usar el método AddRange con una función recursiva, que se llama a sí mismo muy a menudo obtuve una excepción SystemOutOfMemoryException porque se alcanzó el número máximo de dimensiones.

(Mensaje traducido de Google)
Las dimensiones de la matriz superaron el rango admitido.

El uso de Concat resolvió ese problema.


Si existen algunos elementos en ambas listas, puede utilizar

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


Siempre que sean del mismo tipo, es muy simple con AddRange:

list2.AddRange(list1);


Solo quería probar cómo funciona Union con el comparador predeterminado en colecciones superpuestas de objetos de tipo de referencia.

Mi objeto es:

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

Mi código de prueba es:

MyInt[] myInts1 = new MyInt[10]; MyInt[] myInts2 = new MyInt[10]; int overlapFrom = 4; Console.WriteLine("overlapFrom: {0}", overlapFrom); Action<IEnumerable<MyInt>, 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<MyInt> 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));

La salida es:

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

Entonces, todo funciona bien.


Tu podrías intentar:

List<string> a = new List<string>(); List<string> b = new List<string>(); a.AddRange(b);

Página de MSDN para AddRange

Esto conserva el orden de las listas, pero no elimina ningún duplicado que haría Union .

Esto cambia la lista a . Si desea conservar las listas originales, debe usar Concat (como se Concat en las otras respuestas):

var newList = a.Concat(b);

Esto devuelve un IEnumerable siempre y cuando no sea nulo.


Ver este Union

public class ProductA { public string Name { get; set; } public int Code { get; set; } } public class ProductComparer : IEqualityComparer<ProductA> { 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 } };

// Obtener los productos de las dos matrices // excluyendo duplicados.

IEnumerable<ProductA> 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 */


una forma: List.AddRange () dependiendo de los tipos?


List<string> list1 = new List<string>(); list1.Add("dot"); list1.Add("net"); List<string> list2 = new List<string>(); list2.Add("pearls"); list2.Add("!"); var result = list1.Concat(list2);


aList.AddRange( anotherList );


targetList = list1.Concat(list2).ToList();

Está funcionando bien, creo que sí. Como se dijo anteriormente, Concat devuelve una nueva secuencia y, al convertir el resultado en Lista, hace el trabajo perfectamente. Las conversiones implícitas pueden fallar algunas veces cuando se usa el método AddRange.