2017-08-15 6 views
3

私の最初のデータ収集は、このようなものです:2つの辞書のコレクションのLINQクエリに参加する方法

IEnumerable<Dictionary<string, object>> firstSourceData; 

項目は、このようなものです:

new Dictionary<string, object> 
{ 
    ["id"] = 1, 
    ["name"] = "some", 
    ["age"] = 30 
} 

そして、私の第二のデータを別の辞書のコレクションです:

IEnumerable<Dictionary<string, object>> secondSourceData; 

アイテムは次のとおりです。

new Dictionary<string, object> 
{ 
    ["id"] = 1, 
    ["sales"] = 58, 
    ["age"] = 30 
} 

これらの2つのデータは異なるソースからのもので、重複した値を含まない1つの辞書コレクションを作成します。ディクショナリの場合は、Idキーのみが標準であり、他のプロパティは変更される可能性があります。

IEnumerable<Dictionary<string, object>> joined; 

new Dictionary<string, object> 
{ 
    ["id"] = 1, 
    ["sales"] = 58, 
    ["name"] = "some", 
    ["age"] = 30 
}, 

LINQラムダ式でこれを行うにはどうすればよいですか?

+0

だから、あなたがしたいですBに参加するイド? –

+0

はい、IDで参加してください。 – barteloma

+0

@Bookmaster:すべての辞書にid-keyが入っていますか? –

答えて

1

これは、あなたがやって探しているものです。

  • は、辞書の2つのコレクションをマージします。
  • 項目を「id」キー値でグループ化します。
  • 複数の辞書があるので、平文にはSelectManyを使用し、次に鍵にはGroupByを使用します。今すぐ辞書を再作成することができます - ToDictionary。キー自体が繰り返されているので、ネストしたGroupByの値を使用し、目的の値を選択することができます。ここで私はちょうどのでFirstOrDefault

を使用:

var result = firstSourceData.Concat(secondSourceData) 
       .GroupBy(item => item["id"]) 
       .Select(group => group.SelectMany(item => item) 
             .GroupBy(item => item.Key) 
             .ToDictionary(key => key.Key, 
                value => value.FirstOrDefault().Value)); 

これが結果です:このテストケースについては

new Dictionary<string, object> 
{ 
    ["id"] = 1, 
    ["sales"] = 58, 
    ["name"] = "some", 
    ["age"] = 30 
}, 
new Dictionary<string, object> 
{ 
    ["id"] = 2, 
    ["sales"] = 58, 
    ["age"] = 30 
} 

var firstSourceData = new List<Dictionary<string, object>> 
{ 
    new Dictionary<string, object> 
    { 
     ["id"] = 1, 
     ["sales"] = 58, 
     ["age"] = 30 
    }, 
    new Dictionary<string, object> 
    { 
     ["id"] = 2, 
     ["sales"] = 58, 
     ["age"] = 30 
    } 
}; 

var secondSourceData = new List<Dictionary<string, object>> 
{ 
    new Dictionary<string, object> 
    { 
     ["id"] = 1, 
     ["name"] = "some", 
     ["age"] = 30 
    } 
}; 
+1

'.ToDictionary(key => key.Key、value => value.FirstOrDefault()。Value)'は私のために働いています。 Thanks – barteloma

+0

@bookmarker - ops true :)それ以外の場合、値は 'KeyValuePair 'です。修正済み –

+0

idキーを使用せずにこれを実行できますか?あなたは、すべて複製できますか?したがって、すべてのプロパティは新しい辞書に挿入されます。 – barteloma

-1

あなたが行うことができます連合(ソース長差があれば、あらゆる問題がある):

Dictionary<string,object> dict1 = new Dictionary<string, object>(); 
     dict1.Add("id", 1); 
     dict1.Add("name", "Some"); 
     dict1.Add("age", 30); 

     Dictionary<string, object> dict2 = new Dictionary<string, object>(); 
     dict2.Add("id", 1); 
     dict2.Add("sales", 58); 
     dict2.Add("age", 30); 

     Dictionary<string, object> dict3 = new Dictionary<string, object>(); 
     dict3 = dict1.Union(dict2).ToDictionary(c => c.Key, c => c.Value); 

結果の値は以下のとおりです。

[0] = {[id, 1]} 
[1] = {[name, Some]} 
[2] = {[age, 30]} 
[3] = {[sales, 58]} 
+2

'Dictionary 'それはコレクション 'IEnumerabl > 'です。 – barteloma

-1

concat

IEnumerable<Dictionary<string, object>> joined; 

joined= firstSSourceData.Concat(secondSourceData.Where(a => !firstSSourceData.ContainsKey(a.Key))); 
0

でこれを行いますこのようなJoinを使用することができます

from dict1 in firstSourceData 
join dict2 in secondSourceData 
on dict1["id"] equals dict2["id"] 
select dict1.Concat(          //concatenates 2 dictionaries together 
      dict2.Where(kv => !dict1.ContainsKey(kv.Key)) //chooses non-repeating keys 
     ).ToDictionary(kv => kv.Key, kv => kv.Value)  //gets a new dictionary from that 

ソースの長さが異なる場合joinは、idが最初のソースにあるこれらのディクショナリのみを選択します。あなたはすべてのid秒を取得したい場合は、両方に関係なくid秒から辞書をしたい場合は、関係なく、あなたは、両方のソースからのデータを持っているかどうか、あなたはDefaultIfEmpty

from dict1 in firstSourceData 
join tempDict2 in secondSourceData 
on dict1["id"] equals tempDict2["id"] into joined 
from dict2 in joined.DefaultIfEmpty(new Dictionary<string, object>()) //make a new dictionary if there's none 
select dict1.Concat(
      dict2.Where(kv => !dict1.ContainsKey(kv.Key)) 
     ).ToDictionary(kv => kv.Key, kv => kv.Value) 

を使用することができますthis質問を参照してください。

+0

ZipはIdではなくインデックスで結合します。 OPは、すべてのIDと、このIDに属し、すべての辞書にある収集されたすべてのプロパティのコレクションを含むコレクションをフラットにしたいと考えています。 –

+0

でも、opにはそういうことは言及されていません:) –

+0

しかし、あなたは決して言及されなかった仮定をしています。OPは、すべてのidに1つの辞書が必要だと言っています。そのIDに属し、両方のシーケンスのすべての辞書から収集されました。静的な唯一のことは、すべての辞書にid-keyが含まれていることです。 –

関連する問題