2016-07-21 11 views
1

私はC#クラスを持っていますので、それをItemクラスと呼びましょう。 Itemクラスには次のプロパティがあります。複数のリストの項目をPOCOで見つけ、マスターリストでマージするのが最も効率的です

Name 
Region 
Value 

I型itemの複数のオブジェクトを含む4リストを持っています。リストの1つはマスターリストです。

MasterList

Name Region  Value 
A  Global  10 
B  Global  20 
C  Global  30 
D  Global  40 
E  Global  50 
F  Global  60 
G  Global  70 
H  Global  80 
I  Global  90 
J  Global  100 

の内容は次

Name Region  Value 
A  UK   20 
B  UK   20 
C  UK   20 
D  UK   20 
F  UK   20 
UKList の内容に続いUSAList

Name Region  Value 
G  USA   50 
H  USA   50 
I  USA   50 
J  USA   50 
A  USA   50 

のコンテンツれているされています

次はの内容EUList

Name Region  Value 
A  EU   30 
B  EU   30 
D  EK   30 
G  EK   30 
I  EK   30 

どれリストにあるアイテムの数に制限はありません。マスターリストにはすべてのアイテムが含まれます。アイテムはリストに1回しか表示できません。アイテムは、リスト内でソートされていてもソートされていなくてもよい(名前別)。

マスターリストにすべてのアイテムがあると仮定して、すべてのリストからアイテムを探したいと思います。私は名前で項目を見つける必要があります&このように見える新しいリストを作成します。

Name GlobalValue  USAValue  UKValue  EUValue 
A  10    50    20    30 
B  20        20    30 
C  30        20 
D  40        20    30 
E  50 
F  60        20 
G  70    50       30 
H  80    50 
I  90    50       30 
J  100    50 

次のプロパティを持つ新しいクラスを作成できます。

Name, GlobalValue, USAValue, UKValue, EUValue 

それから私は、このループ内のマスターリスト&の上に行くためのループを開始することができ、私は3つの以上のループを実行します。 1人はUSAList、もう1人はUKリスト& EUList用です。それから私は病気の名前で商品を見つけようとすると、私は新しいリストを作成します。

しかし、私は望ましい結果を得るための最も効率的な方法を知りたいと思います。

DEMO CLASS & LISTあなたが提供するサンプルコードで

public class Item 
    { 
     public string Name { get; set; } 
     public string Region { get; set; } 
     public string Value { get; set; } 
    } 

LIST

List<Item> MasterList = new List<Item>(); 
      MasterList.Add(new Item {Name = "A", Region = "Global", Value = "10"}); 
      MasterList.Add(new Item {Name = "B", Region = "Global", Value = "20"}); 
      MasterList.Add(new Item {Name = "C", Region = "Global", Value = "30"}); 
      MasterList.Add(new Item {Name = "D", Region = "Global", Value = "40"}); 
      MasterList.Add(new Item {Name = "E", Region = "Global", Value = "50"}); 
      MasterList.Add(new Item {Name = "F", Region = "Global", Value = "60"}); 
      MasterList.Add(new Item {Name = "G", Region = "Global", Value = "70"}); 
      MasterList.Add(new Item {Name = "H", Region = "Global", Value = "80"}); 
      MasterList.Add(new Item {Name = "I", Region = "Global", Value = "90"}); 
      MasterList.Add(new Item {Name = "J", Region = "Global", Value = "100"}); 

      List<Item> USAList = new List<Item>(); 
      USAList.Add(new Item { Name = "G", Region = "USA", Value = "50" }); 
      USAList.Add(new Item { Name = "H", Region = "USA", Value = "50" }); 
      USAList.Add(new Item { Name = "I", Region = "USA", Value = "50" }); 
      USAList.Add(new Item { Name = "J", Region = "USA", Value = "50" }); 
      USAList.Add(new Item { Name = "A", Region = "USA", Value = "40" }); 

      List<Item> UkList = new List<Item>(); 
      UkList.Add(new Item { Name = "A", Region = "UK", Value = "20" }); 
      UkList.Add(new Item { Name = "B", Region = "UK", Value = "20" }); 
      UkList.Add(new Item { Name = "C", Region = "UK", Value = "20" }); 
      UkList.Add(new Item { Name = "D", Region = "UK", Value = "20" }); 
      UkList.Add(new Item { Name = "F", Region = "UK", Value = "20" }); 

      List<Item> EUList = new List<Item>(); 
      EUList.Add(new Item { Name = "A", Region = "EU", Value = "30" }); 
      EUList.Add(new Item { Name = "B", Region = "EU", Value = "30" }); 
      EUList.Add(new Item { Name = "G", Region = "EU", Value = "30" }); 
      EUList.Add(new Item { Name = "G", Region = "EU", Value = "30" }); 
      EUList.Add(new Item { Name = "I", Region = "EU", Value = "30" }); 
+0

投票の理由はありますか? – OpenStack

+0

downvoterについては話すことはできませんが、おそらくあなたは新しいリストに値を入力する既存のコードを表示する必要があります。それはあなたが私たちにあなたのためにそれを書くように要求しているように見えます。また、「最も効率的」という意味を定義することもできますか? – stuartd

+0

@stuartd:ありがとう。私は質問を更新します。 – OpenStack

答えて

1

、あなたの代わりに他のリストのmasterlistするすべての項目を追加しますが、偶然、それはほとんどのかもしれません複数の結合の代わりにGroupByを使用してリストを連結します。

var list = (from i in MasterList.Concat(USAList).Concat(UkList).Concat(EUList) //concat all lists 
      group i by i.Name into g //primary group by on Name 
      let d = (IDictionary)g.GroupBy(si=>si.Region).ToDictionary(gr => gr.Key, gr=> gr.Sum(v=>int.Parse(v.Value))) //create a dictionary of regions with the sums as values 
      select new {Name = g.Key, GlobalValue = d["Global"], USAValue = d["USA"], UKValue = d["UK"], EUValue = d["EU"]}).ToList(); 

個別のフィールドの代わりに、値辞書自体を追加できます。 (IDictionary)へのキャストにも注意してください。 'IDictionary'インデックスの実装は、汎用インデックスの直接インデックスとは異なる動作をします。後者は、辞書にないインデックスの例外をスローします。

テスト用:dotnetfiddle

+0

ありがとうRobert Verpalen :)すばらしい答えに投票しますが、答えとしてマークする前に目的の結果を得るより効率的な方法があるかどうかを確認するのを待っています! ! – OpenStack

+0

この文で何をしているのか説明できますか?let d =(IDictionary)g.GroupBy(si => si.Region).ToDictionary(gr => gr.Key、gr => gr.Sum(v =>値の和で領域の辞書を作成する ' – OpenStack

+0

確かに:' let'はクエリの構文で中間値を宣言する方法なので、 'd'は宣言された。 'g'はその上の行に作成された名前のグループです。したがって、それぞれの名前に対して、 'g'にはすべてのItemが含まれています。この行では、これらの名前グループは地域別にグループ化されています。実行中は、単一の名前のグループがそのリージョンにグループ化されていることを意味します。そのグループから、各キー(領域)について、すべての「アイテム」値の合計を値として有する辞書が作成される。最終的に、dにはすべての地域の辞書が含まれ、 'Name'が繰り返される量が含まれています –

関連する問題