web-dev-qa-db-ja.com

C#.NETで、2つ(またはそれ以上)のリストを1つにマージする

C#を使用して.NETで1つのリストに複数のリストを変換することは可能ですか?

例えば、

public static List<Product> GetAllProducts(int categoryId){ .... }
.
.
.
var productCollection1 = GetAllProducts(CategoryId1);
var productCollection2 = GetAllProducts(CategoryId2);
var productCollection3 = GetAllProducts(CategoryId3);
198
zekia

LINQ Concat および ToList メソッドを使用できます。

var allProducts = productCollection1.Concat(productCollection2)
                                    .Concat(productCollection3)
                                    .ToList();

これを行うにはより効率的な方法があることに注意してください - 上記は基本的にすべてのエントリをループし、動的サイズのバッファを作成します。最初にサイズを予測できるので、この動的なサイズ変更は必要ありません。したがって、を使用できます。

var allProducts = new List<Product>(productCollection1.Count +
                                    productCollection2.Count +
                                    productCollection3.Count);
allProducts.AddRange(productCollection1);
allProducts.AddRange(productCollection2);
allProducts.AddRange(productCollection3);

AddRangeは効率を上げるためにICollection<T>専用です。)

あなたが本当にしなければならない限り、私はこのアプローチをとらないでしょう。

376
Jon Skeet

指定したカテゴリIDの商品の all を含むリストが必要であると仮定すると、クエリを射影とそれに続くaとして扱うことができます。 平坦化操作それを行うLINQ演算子があります。 SelectMany

// implicitly List<Product>
var products = new[] { CategoryId1, CategoryId2, CategoryId3 }
                     .SelectMany(id => GetAllProducts(id))
                     .ToList();

C#4では、SelectManyを次のように短くすることができます。.SelectMany(GetAllProducts)

各IDの商品を表すリストがすでにある場合は、他の人が指摘するように、必要なのは連結です。

38
Ani

lINQを使ってそれらを組み合わせることができます:

  list = list1.Concat(list2).Concat(list3).ToList();

ただし、List.AddRange()を使用するより伝統的なアプローチはもっと効率的かもしれません。

21
Botz3000

あなたは Concat 拡張メソッドを使うことができます:

var result = productCollection1
    .Concat(productCollection2)
    .Concat(productCollection3)
    .ToList();
7
Darin Dimitrov
list4 = list1.Concat(list2).Concat(list3).ToList();
7
decyclone

リストをマージするには、 List.AddRange をご覧ください。

7
StuartLC

私はすでにそれをコメントしました、しかし私はまだあなたの環境でどちらが良い解決策であるかどうかテストするだけで有効な選択肢であると思います。私の特定のケースでは、source.ForEach(p => dest.Add(p))を使用することは、古典的なAddRangeよりもパフォーマンスが良くなりますが、私はその理由を低レベルで調査していません。

ここにコード例があります。 https://Gist.github.com/mcliment/4690433

したがって、オプションは次のようになります。

var allProducts = new List<Product>(productCollection1.Count +
                                    productCollection2.Count +
                                    productCollection3.Count);

productCollection1.ForEach(p => allProducts.Add(p));
productCollection2.ForEach(p => allProducts.Add(p));
productCollection3.ForEach(p => allProducts.Add(p));

それがあなたのために働くかどうか確かめるためにそれをテストしてください。

免責事項:私はこの解決策を提唱していません、私はConcatが最も明確なものだと思っています。 Jonとの話し合いの中で、私のマシンではこのケースのほうがAddRangeよりも優れていることを述べました。比較したい場合は要点があります。

2
Marc Climent

私はこれが私がちょうど私の2セントを加えるかもしれないと思った古い質問であることを知っています。

あなたがList<Something>[]を持っているなら、あなたはそれらをAggregateを使って結合することができます

public List<TType> Concat<TType>(params List<TType>[] lists)
{
    var result = lists.Aggregate(new List<TType>(), (x, y) => x.Concat(y).ToList());

    return result;
}

お役に立てれば。

1
sQuir3l

リストを1つのリストにマージまたは結合すること。

  • 真実でなければならないことが1つあります。両方のリストの型が等しくなることです。

  • の場合:もしstringのリストがあれば、既存のリストに追加できるので文字列型のリストを追加できます。そうでなければできません。

class Program
{
   static void Main(string[] args)
   {
      List<string> CustomerList_One = new List<string> 
      {
         "James",
         "Scott",
         "Mark",
         "John",
         "Sara",
         "Mary",
         "William",
         "Broad",
         "Ben",
         "Rich",
         "Hack",
         "Bob"
      };

      List<string> CustomerList_Two = new List<string> 
      {
         "Perter",
         "Parker",
         "Bond",
         "been",
         "Bilbo",
         "Cooper"
      };

      // Adding all contents of CustomerList_Two to CustomerList_One.
      CustomerList_One.AddRange(CustomerList_Two);

      // Creating another Listlist and assigning all Contents of CustomerList_One.
      List<string> AllCustomers = new List<string>();

      foreach (var item in CustomerList_One)
      {
         AllCustomers.Add(item);
      }

      // Removing CustomerList_One & CustomerList_Two.
      CustomerList_One = null;

      CustomerList_Two = null;
      // CustomerList_One & CustomerList_Two -- (Garbage Collected)
      GC.Collect();

      Console.WriteLine("Total No. of Customers : " +  AllCustomers.Count());
      Console.WriteLine("-------------------------------------------------");
      foreach (var customer in AllCustomers)
      {
         Console.WriteLine("Customer : " + customer);
      }
      Console.WriteLine("-------------------------------------------------");

   }
}
1
Rehan Shah
// I would make it a little bit more simple

 var products = new List<List<product>> {item1, item2, item3 }.SelectMany(id => id).ToList();

このようにそれは多次元リストであり、そして.SelectMany()はそれを製品のIEnumerableに平坦化するでしょうそして私はその後.ToList()メソッドを使用します。

1
Gringo Jaimes

特別な場合: "List1の全ての要素は新しいList2に行きます":(例えば文字列リスト)

List<string> list2 = new List<string>(list1);

この場合、list2は、list1のすべての要素で生成されます。

0
Arthur Zennig

Concat操作を使用する必要があります

0
Artem

あなたがリストをほとんど持っていなくても、正確にいくつがリストされているかわからないときは、これを使ってください。

listsOfProductsはオブジェクトで埋められたリストをほとんど含んでいません。

List<Product> productListMerged = new List<Product>();

listsOfProducts.ForEach(q => q.ForEach(e => productListMerged.Add(e)));
0
john.kernel