Как объединить списки в 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)


arrow_upward
342
arrow_downward

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

person John Kugelman    schedule 25.06.2009

arrow_upward
106
arrow_downward

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

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

arrow_upward
12
arrow_downward

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

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

person Balasubramani M    schedule 23.06.2014

arrow_upward
5
arrow_downward

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

arrow_upward
2
arrow_downward

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

arrow_upward
2
arrow_downward

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

 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