Como você concatena listas em c #?

171

Se eu tiver:

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?

Eu executei um código semelhante a esse no Visual Studio 2008 e defina pontos de interrupção após cada execução. Depois myList1 = getMeAList();, myList1contém quatro strings e pressionei o botão de adição para garantir que não fossem todos nulos.

Depois myList2 = getMeAnotherList();, myList2contém seis strings, e eu verifiquei para garantir que elas não fossem nulas ... Depois que myList1.Concat(myList2);myList1 continha apenas quatro strings. Por que é que?

Matt
fonte

Respostas:

97

Tente o seguinte:

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

Concat retorna um IEnumerable <T> que são as duas listas reunidas, não modifica nenhuma das listas existentes. Além disso, como ele retorna um IEnumerable, se você quiser atribuí-lo a uma variável que é List <T>, precisará chamar ToList () no IEnumerable <T> retornado.

Jonathan Rupp
fonte
6
Agora que reli a pergunta, .AddRange () soa como o que o OP realmente deseja.
Jonathan Rupp
@Kartiikeya se ele está dizendo que os argumentos são inválidos, você não tem uma instrução using para System.Linq, ou um deles não é umaIEnumerable<T>
Jonathan Rupp
12
targetList = list1.Concat(list2).ToList();

Está funcionando bem, acho que sim. Como dito anteriormente, o Concat retorna uma nova sequência e, ao converter o resultado em Lista, ele executa o trabalho perfeitamente.

Balasubramani M
fonte
4

Também vale notar que o Concat trabalha em tempo constante e em memória constante. Por exemplo, o seguinte código

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

fornece as seguintes métricas de tempo / memória:

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

Eu sei que isso é antigo, mas me deparei com este post rapidamente pensando que Concat seria a minha resposta. Union funcionou muito bem para mim. Observe que ele retorna apenas valores únicos, mas sabendo que eu estava obtendo valores únicos de qualquer maneira, essa solução funcionou para mim.

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

A saída é:

One
Two
Three
1234
4567
Esaith
fonte
2

Dê uma olhada na minha implementação. É seguro contra listas nulas.

 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
fonte