web-dev-qa-db-ja.com

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には4つの文字列が含まれています。プラスボタンを押して、すべてがヌルではないことを確認しました。

myList2 = getMeAnotherList();の後、myList2には6つの文字列が含まれ、それらがnullでないことを確認しました... myList1.Concat(myList2);の後、myList1には4つの文字列のみが含まれていました。何故ですか?

149
Matt

Concatは、新しいシーケンスを返します 元のリストを変更せずにmyList1.AddRange(myList2)を試してください。

266
John Kugelman

これを試して:

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

Concat は、2つのリストをまとめたIEnumerable <T>を返します。既存のリストは変更しません。また、IEnumerableを返すため、List <T>である変数に割り当てる場合は、返されるIEnumerable <T>でToList()を呼び出す必要があります。

82
Jonathan Rupp
targetList = list1.Concat(list2).ToList();

それはうまくいくと思う。前に述べたように、Concatは新しいシーケンスを返し、結果をリストに変換しながら、完璧に仕事をします。

8
Balasubramani M

また、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
3

私の実装を見てくださいits safe from null lists

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