Bagaimana Anda menggabungkan Daftar di C #?

171

Jika saya punya:

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?

Saya menjalankan kode yang mirip dengan ini di Visual Studio 2008 dan menetapkan titik istirahat setelah setiap eksekusi. Setelah myList1 = getMeAList();, myList1berisi empat string, dan saya menekan tombol plus untuk memastikan semuanya tidak nol.

Setelah myList2 = getMeAnotherList();, myList2berisi enam string, dan saya memeriksa untuk memastikan mereka tidak nol ... Setelah myList1.Concat(myList2);myList1 hanya berisi empat string. Mengapa demikian?

Mat
sumber

Jawaban:

97

Coba ini:

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

Concat mengembalikan IEnumerable <T> yang merupakan dua daftar yang disatukan, itu tidak mengubah daftar yang ada. Juga, karena mengembalikan IEnumerable, jika Anda ingin menetapkannya ke variabel yang Daftar <T>, Anda harus memanggil ToList () pada IEnumerable <T> yang dikembalikan.

Jonathan Rupp
sumber
6
Sekarang saya membaca kembali pertanyaannya, .AddRange () memang terdengar seperti apa yang benar-benar diinginkan OP.
Jonathan Rupp
@Kartiikeya jika mengatakan argumen tidak valid, Anda tidak memiliki pernyataan menggunakan untuk System.Linq, atau salah satunya bukanIEnumerable<T>
Jonathan Rupp
12
targetList = list1.Concat(list2).ToList();

Saya pikir itu berfungsi dengan baik. Seperti yang dikatakan sebelumnya, Concat mengembalikan urutan baru dan ketika mengubah hasilnya menjadi Daftar, ia melakukan pekerjaan dengan sempurna.

Balasubramani M
sumber
4

Perlu juga dicatat bahwa Concat bekerja dalam waktu dan memori yang konstan. Misalnya, kode berikut

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

memberikan metrik waktu / memori berikut:

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

Saya tahu ini sudah tua tetapi saya menemukan posting ini dengan cepat berpikir Concat akan menjadi jawaban saya. Union bekerja dengan baik untuk saya. Catatan, ini hanya mengembalikan nilai unik tetapi mengetahui bahwa saya mendapatkan nilai unik pula solusi ini berhasil untuk saya.

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

Outputnya adalah:

One
Two
Three
1234
4567
Esaith
sumber
2

Lihatlah implementasi saya. Aman dari daftar nol.

 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
sumber