¿Cómo se concatenan las listas en C #?

171

Si tengo:

List<string> myList1;
List<string> myList2;

myList1 = getMeAList();
// Checked myList1, it contains 4 strings

myList2 = getMeAnotherList();
// Checked myList2, it contains 6 strings

myList1.Concat(myList2);
// Checked mylist1, it contains 4 strings... why?

Ejecuté un código similar a este en Visual Studio 2008 y establecí puntos de interrupción después de cada ejecución. Después myList1 = getMeAList();, myList1contiene cuatro cadenas, y presioné el botón más para asegurarme de que no fueran todas nulas.

Después myList2 = getMeAnotherList();, myList2contiene seis cadenas, y verifiqué para asegurarme de que no fueran nulas ... Después de que myList1.Concat(myList2);myList1 contuviera solo cuatro cadenas. ¿Porqué es eso?

Mate
fuente

Respuestas:

97

Prueba esto:

myList1 = myList1.Concat(myList2).ToList();

Concat devuelve un IEnumerable <T> que son las dos listas juntas, no modifica ninguna de las listas existentes. Además, dado que devuelve un IEnumerable, si desea asignarlo a una variable que es List <T>, deberá llamar a ToList () en el IEnumerable <T> que se devuelve.

Jonathan Rupp
fuente
66
Ahora que releí la pregunta, .AddRange () suena como lo que realmente quiere el OP.
Jonathan Rupp
@Kartiikeya si dice que los argumentos no son válidos, no tiene una declaración de uso para System.Linq, o uno de ellos no es unIEnumerable<T>
Jonathan Rupp
12
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.

Balasubramani M
fuente
4

También vale la pena señalar que Concat funciona en tiempo constante y en memoria constante. Por ejemplo, el siguiente código

        long boundary = 60000000;
        for (long i = 0; i < boundary; i++)
        {
            list1.Add(i);
            list2.Add(i);
        }
        var listConcat = list1.Concat(list2);
        var list = listConcat.ToList();
        list1.AddRange(list2);

da las siguientes métricas de tiempo / memoria:

After lists filled mem used: 1048730 KB
concat two enumerables: 00:00:00.0023309 mem used: 1048730 KB
convert concat to list: 00:00:03.7430633 mem used: 2097307 KB
list1.AddRange(list2) : 00:00:00.8439870 mem used: 2621595 KB
Dmitry Andrievsky
fuente
2

Sé que esto es viejo, pero me encontré con esta publicación rápidamente pensando que Concat sería mi respuesta. Union funcionó muy bien para mí. Tenga en cuenta que solo devuelve valores únicos, pero sabiendo que estaba obteniendo valores únicos de todos modos, esta solución funcionó para mí.

namespace TestProject
{
    public partial class Form1 :Form
    {
        public Form1()
        {
            InitializeComponent();

            List<string> FirstList = new List<string>();
            FirstList.Add("1234");
            FirstList.Add("4567");

            // In my code, I know I would not have this here but I put it in as a demonstration that it will not be in the secondList twice
            FirstList.Add("Three");  

            List<string> secondList = GetList(FirstList);            
            foreach (string item in secondList)
                Console.WriteLine(item);
        }

        private List<String> GetList(List<string> SortBy)
        {
            List<string> list = new List<string>();
            list.Add("One");
            list.Add("Two");
            list.Add("Three");

            list = list.Union(SortBy).ToList();

            return list;
        }
    }
}

El resultado es:

One
Two
Three
1234
4567
Esaith
fuente
2

Echa un vistazo a mi implementación. Está a salvo de las listas nulas.

 IList<string> all= new List<string>();

 if (letterForm.SecretaryPhone!=null)// first list may be null
     all=all.Concat(letterForm.SecretaryPhone).ToList();

 if (letterForm.EmployeePhone != null)// second list may be null
     all= all.Concat(letterForm.EmployeePhone).ToList(); 

 if (letterForm.DepartmentManagerName != null) // this is not list (its just string variable) so wrap it inside list then concat it 
     all = all.Concat(new []{letterForm.DepartmentManagerPhone}).ToList();
Basheer AL-MOMANI
fuente