คุณเชื่อมต่อรายการใน C # ได้อย่างไร


170

ถ้าฉันมี:

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?

ฉันรันโค้ดที่คล้ายกับสิ่งนี้ใน Visual Studio 2008 และกำหนดจุดพักหลังจากการดำเนินการแต่ละครั้ง หลังจากmyList1 = getMeAList();, myList1มีสี่สายและผมกดปุ่มบวกเพื่อให้แน่ใจว่าพวกเขาไม่ได้ nulls ทั้งหมด

หลังจาก myList2 = getMeAnotherList();, myList2มีหกสายและฉันจะตรวจสอบเพื่อให้แน่ใจว่าพวกเขาไม่ได้ null ... หลังจากmyList1.Concat(myList2);myList1 มีเพียงสี่สาย ทำไมถึงเป็นอย่างนั้น?

คำตอบ:


303

Concatผลตอบแทนที่ได้ลำดับใหม่โดยไม่มีการแก้ไขรายชื่อเดิม ลองmyList1.AddRange(myList2)ดู


96

ลองสิ่งนี้:

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

Concatส่งคืนค่า IEnumerable <T> ที่เป็นสองรายการที่รวมกัน แต่ไม่ได้แก้ไขรายการที่มีอยู่ นอกจากนี้เนื่องจากมันส่งคืน IEnumerable หากคุณต้องการกำหนดให้กับตัวแปรที่เป็น List <T> คุณจะต้องเรียก ToList () บน IEnumerable <T> ที่ส่งคืน


6
ตอนนี้ฉันอ่านคำถามอีกครั้ง. AddRange () ทำเสียงเหมือนที่ OP ต้องการจริงๆ
Jonathan Rupp

@Kartiikeya ถ้ามันบอกว่าข้อโต้แย้งนั้นไม่ถูกต้องคุณไม่มีคำสั่งการใช้งานสำหรับ System.Linq หรือหนึ่งในนั้นไม่ได้เป็นIEnumerable<T>
Jonathan Rupp

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

มันใช้งานได้ดีฉันคิดอย่างนั้น ดังที่ได้กล่าวไปแล้วก่อนหน้านี้ว่า Concat ส่งคืนลำดับใหม่และในขณะที่การแปลงผลลัพธ์เป็นรายการจะทำงานได้อย่างสมบูรณ์แบบ


4

นอกจากนี้ยังเป็นที่น่าสังเกตว่า Concat ทำงานในเวลาคงที่และในหน่วยความจำคงที่ ตัวอย่างเช่นรหัสต่อไปนี้

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

ให้เมตริกเวลา / หน่วยความจำต่อไปนี้:

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

ฉันรู้ว่ามันเก่า แต่ฉันมาที่โพสต์นี้อย่างรวดเร็วคิดว่า Concat จะเป็นคำตอบของฉัน ยูเนี่ยนทำงานได้ดีสำหรับฉัน หมายเหตุมันจะส่งกลับเฉพาะค่าที่ไม่ซ้ำกัน แต่รู้ว่าฉันได้รับค่าที่ไม่ซ้ำกันแล้วโซลูชันนี้ได้ผลสำหรับฉัน

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

ผลลัพธ์คือ:

One
Two
Three
1234
4567

2

ดูการใช้งานของฉัน ปลอดภัยจากรายการว่าง

 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();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.