Як ви об'єднаєте списки в 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містить чотири рядки, і я натиснув кнопку плюс, щоб переконатися, що вони не всі нулі.

Після myList2 = getMeAnotherList();, myList2містить шість рядків, і я перевірив, щоб вони не були нульовими ... Після того, як myList1.Concat(myList2);myList1 містив лише чотири рядки. Чому так?

Відповіді:



96

Спробуйте це:

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

Concat повертає IEnumerable <T>, що є двома списками, складеними разом, він не змінює жодного існуючого списку. Крім того, оскільки він повертає IEnumerable, якщо ви хочете призначити його змінній, що є List <T>, вам доведеться викликати ToList () на поверненому IEnumerable <T>.


6
Тепер, коли я перечитував питання, .AddRange () звучить як те, що ОП насправді хоче.
Джонатан Рупп

@Kartiikeya, якщо він говорить про те, що аргументи недійсні, у вас немає оператора, що використовує System.Linq, або один з них не єIEnumerable<T>
Джонатан Рупп,

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

Я думаю, що так. Як було сказано раніше, Concat повертає нову послідовність і, перетворюючи результат у List, виконує цю роботу ідеально.


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();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.