3

Linqクエリの作成についてサポートが必要です。私はこの辞書を持っています:

var dict = new Dictionary<string, IDictionary<int, double>>  
{  
    { "one", new Dictionary<int, double>  
        {  
            { 1, 2.0 },  
            { 2, 3.0 }  
        }},  
    { "two", new Dictionary<int, double>  
        {  
            { 1, 3.0 },  
            { 2, 4.0 },  
            { 3, 5.0 }  
        }},  
    { "three", new Dictionary<int, double>  
        {  
            { 1, 4.0 },  
            { 2, 5.0}  
        }}  
    };  

関連する値が3.0のすべての「string」/「int」タプルを選択したい。Foreachループを使用すると、次のようになります。

var res = new Dictionary<string, int>();
foreach (var elem in dict.Select (d => new { S = d.Key, I = d.Value }))
{
    foreach (var val in elem.I)
    {
        if (val.Value == 3.0)
        {
            res.Add(elem.S, val.Key);
        }
    }
}

単一のLinqクエリで同じことを行おうとしていますが、成功しません(サブクエリの値を使用してキーを「結合」する方法がわかりません)。これをどのように行いますか?

前もって感謝します!

4

3 に答える 3

3

これを行う別のお尻の醜い方法は次のとおりです。

var results = from key1 in dict.Keys
              let valueDict = dict[key1]
              from key2 in valueDict.Keys
              where valueDict[key2] == 3d
              select new { Key1 = key1, Key2 = key2 };
于 2013-01-08T17:16:28.260 に答える
3

これはトリックを行います:

var  res = dict
        .Where(outer => outer.Value.Any(inner => inner.Value == 3.0))
        .ToDictionary(outer => outer.Key, outer => outer.Value.First(x=>x.Value == 3.0).Key);

または、コードをもう少し一般的にするには:

var predicate = new Func<KeyValuePair<int, double>, bool>(inner => inner.Value == 3.0); 
var  res = dict
        .Where(outer => outer.Value.Any(inner => predicate(inner)))
        .ToDictionary(outer => outer.Key, outer => outer.Value.First(inner => predicate(inner)).Key);
于 2013-01-08T17:12:20.463 に答える
3

あなたはこのようにそれを行うことができます:

var result = dict
    // flatten to 3-value tuple
    .SelectMany(kvp => kvp.Value
        .Select(kvp2 => new // anonymous object
        {
            OuterKey = kvp.Key, // e.g. "one"
            InnerKey = kvp2.Key, // e.g. 1
            InnerValue = kvp2.Value // e.g. 2.0
        })
    ).Where(o => o.InnerValue == 3.0) // limit to the 3.0 value
    .ToDictionary(o => o.OuterKey, o => o.InnerKey)
    ;

SelectManyは、辞書の辞書を次のような構造にフラット化します。

{ OuterKey = "one", InnerKey = 1, InnerValue = 2.0 },
{ OuterKey = "one", InnerKey = 2, InnerValue = 3.0 },
{ OuterKey = "two", InnerKey = 1, InnerValue = 3.0 },
{ OuterKey = "two", InnerKey = 2, InnerValue = 4.0 },
{ OuterKey = "two", InnerKey = 3, InnerValue = 5.0 },
{ OuterKey = "three", InnerKey = 1, InnerValue = 4.0 },
{ OuterKey = "three", InnerKey = 2, InnerValue = 5.0 }

Where()は、InnerValue=3.0のオブジェクトのみに制限します。

{ OuterKey = "one", InnerKey = 2, InnerValue = 3.0 },
{ OuterKey = "two", InnerKey = 1, InnerValue = 3.0 }

ToDictionary()は次のようになります。

{ "one", 2 },
{ "two", 1 }

同じ外部キーの下に複数の3.0が存在する可能性がある場合は、ToDictionary()の代わりにToLookup()を使用できます。

于 2013-01-08T17:55:38.503 に答える