Как объединить списки в C #?

Если бы у меня был:

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 содержал только четыре строки. Это почему?


person Matt    schedule 25.06.2009    source источник


Ответы (6)


Concat возвращает новую последовательность без изменения исходного списка. Попробуйте myList1.AddRange(myList2).

person John Kugelman    schedule 25.06.2009

Попробуй это:

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

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

person Jonathan Rupp    schedule 25.06.2009
comment
Теперь, когда я перечитал вопрос, .AddRange () действительно звучит так, как действительно хочет OP. - person Jonathan Rupp; 25.06.2009
comment
@Kartiikeya, если он говорит, что аргументы недействительны, у вас нет оператора using для System.Linq или один из них не является IEnumerable<T> - person Jonathan Rupp; 11.06.2015

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

Думаю, все работает нормально. Как было сказано ранее, Concat возвращает новую последовательность и, преобразуя результат в List, отлично справляется со своей задачей.

person Balasubramani M    schedule 23.06.2014

Также стоит отметить, что 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
person Dmitry Andrievsky    schedule 22.11.2014

Я знаю, что это старый, но я быстро наткнулся на этот пост, подумав, что 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
person Esaith    schedule 28.09.2015

Взгляните на мою реализацию. Это безопасно от нулевых списков.

 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();
person Basheer AL-MOMANI    schedule 21.09.2016