Wie verketten Sie Listen in C #?

170

Wenn ich habe:

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?

Ich habe in Visual Studio 2008 ähnlichen Code ausgeführt und nach jeder Ausführung Haltepunkte festgelegt. Nach dem myList1 = getMeAList();, myList1enthält vier Saiten, und ich drückte die Plus - Taste , um sicherzustellen , sie waren nicht alle Nullen.

Nach dem myList2 = getMeAnotherList();, myList2enthält sechs Saiten, und ich überprüft , um sicherzustellen , sie nicht null waren ... Nach myList1.Concat(myList2);mylist1 nur vier Saiten enthalten. Warum ist das so?

Matt
quelle

Antworten:

96

Versuche dies:

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

Concat gibt ein IEnumerable <T> zurück, dh die beiden Listen zusammen. Es ändert keine der vorhandenen Listen. Da es eine IEnumerable zurückgibt, müssen Sie ToList () für die zurückgegebene IEnumerable <T> aufrufen, wenn Sie sie einer Variablen namens List <T> zuweisen möchten.

Jonathan Rupp
quelle
6
Nachdem ich die Frage erneut gelesen habe, klingt .AddRange () so, wie es das OP wirklich will.
Jonathan Rupp
@ Kartiikeya Wenn es heißt, dass die Argumente ungültig sind, haben Sie keine using-Anweisung für System.Linq, oder eine davon ist keineIEnumerable<T>
Jonathan Rupp
12
targetList = list1.Concat(list2).ToList();

Es funktioniert gut, denke ich. Wie bereits erwähnt, gibt Concat eine neue Sequenz zurück und erledigt das Ergebnis perfekt, während es das Ergebnis in List konvertiert.

Balasubramani M.
quelle
4

Es ist auch erwähnenswert, dass Concat in konstanter Zeit und in ständigem Gedächtnis arbeitet. Zum Beispiel der folgende Code

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

gibt die folgenden Timing- / Speichermetriken an:

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
quelle
2

Ich weiß, dass dies alt ist, aber ich bin schnell auf diesen Beitrag gestoßen und dachte, Concat wäre meine Antwort. Union hat großartig für mich funktioniert. Beachten Sie, dass nur eindeutige Werte zurückgegeben werden. Da ich jedoch wusste, dass ich ohnehin eindeutige Werte erhalten habe, hat diese Lösung für mich funktioniert.

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

Die Ausgabe ist:

One
Two
Three
1234
4567
Esaith
quelle
2

Schauen Sie sich meine Implementierung an. Es ist sicher vor Nulllisten.

 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
quelle