Come concatenate gli elenchi in C #?


171

Se ho:

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?

Ho eseguito codice simile a questo in Visual Studio 2008 e ho impostato i punti di interruzione dopo ogni esecuzione. Dopo myList1 = getMeAList();, myList1contiene quattro stringhe e ho premuto il pulsante più per assicurarmi che non fossero tutti nulli.

Dopo myList2 = getMeAnotherList();, myList2contiene sei stringhe e ho verificato che non fossero null ... Dopo myList1.Concat(myList2);myList1 conteneva solo quattro stringhe. Perché?

Risposte:



97

Prova questo:

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

Concat restituisce un IEnumerable <T> che è le due liste messe insieme, non modifica nessuna delle liste esistenti. Inoltre, poiché restituisce un IEnumerable, se si desidera assegnarlo a una variabile che è List <T>, è necessario chiamare ToList () su IEnumerable <T> che viene restituito.


6
Ora che rileggo la domanda, .AddRange () suona come quello che l'OP vuole davvero.
Jonathan Rupp,

@Kartiikeya se sta dicendo che gli argomenti non sono validi, non hai una dichiarazione using per System.Linq, o uno di loro non è unIEnumerable<T>
Jonathan Rupp

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

Funziona bene, penso di si. Come detto in precedenza, Concat restituisce una nuova sequenza e durante la conversione del risultato in Elenco, esegue perfettamente il lavoro.


4

Vale anche la pena notare che Concat funziona a tempo costante e in memoria costante. Ad esempio, il seguente codice

        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);

fornisce le seguenti metriche di tempismo / 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

2

So che questo è vecchio ma mi sono imbattuto in questo post pensando rapidamente che Concat sarebbe stata la mia risposta. L'unione ha funzionato alla grande per me. Nota, restituisce solo valori univoci ma sapendo che stavo ottenendo valori unici comunque questa soluzione ha funzionato per me.

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;
        }
    }
}

L'output è:

One
Two
Three
1234
4567

2

Dai un'occhiata alla mia implementazione. È al sicuro da liste nulle.

 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();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.