5

タイプシグネチャを持つ2つのソート済み辞書があります

すなわち

SortedDictionary<decimal, long> A
SortedDictionary<decimal, long> B

キーが同じ2つのリストをマージして、次のような新しいリストを作成したい

SortedDictionary<decimal, KeyValuePair<long,long>>
or
SortedDictionary<decimal, List<long>>

これは状況にアプローチする最善の方法ではないかもしれませんが、誰かがこれを行う方法またはより良いアプローチ方法について頭を上げてくれるでしょうか.

4

5 に答える 5

0

これを行う別の LINQ の方法は、セット操作の点で意図をよりよく捉えていると思います。

SortedDictionary<decimal, long> a = new SortedDictionary<decimal, long>();
SortedDictionary<decimal, long> b = new SortedDictionary<decimal, long>();

a.Add(0, 10);
a.Add(1, 10);
a.Add(2, 100);
a.Add(100, 1);

b.Add(0, 4);
b.Add(4, 4);
b.Add(2, 10);

var result = a.Union(b)
    .GroupBy(x => x.Key)
    .ToDictionary(x => x.Key, x => x.Select(y => (long)y.Value).ToList());
于 2012-04-11T13:03:19.110 に答える
0

次のようなことを試してみてください。簡単ではありません。

Dictionary<decimal, long> dic1 = new Dictionary<decimal, long>{ {3,23}, {2,3}, {5,4}, {6,8}};
    Dictionary<decimal, long> dic2 = new Dictionary<decimal, long>{ {3,2}, {2,5}, {5,14}, {12,2}};


    //recover shared keys (the keys that are present in both dictionaries)
    var sharedKeys = dic1.Select(dic => dic.Key).Intersect(dic2.Select(d2=>d2.Key));
    sharedKeys.Dump();

    //add to the fìnal dictionary
    var final = new Dictionary<decimal, List<long>>();
    foreach(var shk in  sharedKeys) {

       if(!final.ContainsKey(shk)) 
          final[shk] = new List<long>(); 

        final[shk].Add(dic1[shk]);
        final[shk].Add(dic2[shk]);
    }

**EDIT** 
//Skip below part if you need only keys present on both dictionaries.
///-----------------------------------------------------------------

    //get unique keys present in Dic1 and add
    var nonsharedkeys1 = dic1.Select(d=>d.Key).Where(k=>!sharedKeys.Contains(k)); 
    foreach(var nshk in  nonsharedkeys1) {

        final[nshk] = new List<long>();             
        final[nshk].Add(dic1[nshk]);        
    }

     //get unique keys present in Dic2 and add
    var nonsharedkeys2 =  dic2.Select(d=>d.Key).Where(k=>!sharedKeys.Contains(k));
    foreach(var nshk in  nonsharedkeys2) {

        final[nshk] = new List<long>();             
        final[nshk].Add(dic2[nshk]);        
    }

あなたのために働くはずです。

于 2012-04-11T13:05:15.013 に答える
0

あなたは「乱用」ConcatしてAggregate次のようにすることができます:

var A = new SortedDictionary<decimal,long>();
var B = new SortedDictionary<decimal,long>();

A.Add(1, 11);
A.Add(2, 22);
A.Add(3, 33);

B.Add(2, 222);
B.Add(3, 333);
B.Add(4, 444);

var C = A.Concat(B).Aggregate(
    new SortedDictionary<decimal, List<long>>(),
    (result, pair) => {
        List<long> val;
        if (result.TryGetValue(pair.Key, out val))
            val.Add(pair.Value);
        else
            result.Add(pair.Key, new[] { pair.Value }.ToList());
        return result;
    }
);

foreach (var x in C)
    Console.WriteLine(
        string.Format(
            "{0}:\t{1}",
            x.Key,
            string.Join(", ", x.Value)
        )
    );

結果の出力:

1:      11
2:      22, 222
3:      33, 333
4:      444

これは、「通常」を記述した場合とほとんど同じであり、実際には( だけでなく)foreachどんなものでも機能し、必要に応じて 3 つ以上の入力コレクションに簡単に拡張できます。IEnumerable<KeyValuePair<decimal, long>>SortedDictionary<decimal, long>

SortedDictionary残念ながら、入力がソートされているという事実も完全に無視しているため、パフォーマンスは最適ではありません。IEnumerator最適なパフォーマンスを得るには、基になる要素を常に比較しながら、入力ソートされた辞書ごとに個別に直線的に進める必要があります-TryGetValueその方法を完全に回避できます...

于 2012-04-11T13:45:46.210 に答える