2

交差させたい 2 つのコレクションがあり、一致する要素に対して合計操作を実行します。

たとえば、コレクションは次のとおりです (疑似コード)。

col1 = { {"A", 5}, {"B", 3}, {"C", 2} }
col2 = { {"B", 1}, {"C", 8}, {"D", 6} }

望ましい結果は次のとおりです。

intersection = { {"B", 4}, {"C", 10} }

を使用して名前の要素を一致させる方法は知ってIEqualityComparerいますが、交差点を実行しながら値を合計する方法は?

編集:

開始コレクションに同じ名前のアイテムが 2 つありません。

4

4 に答える 4

1

私がこれまでに思いついた最高のものは(私のコレクションは実際にはDictionary<string, int>インスタンスです):

var intersectingKeys = col1.Keys.Intersect(col2.Keys);
var intersection = intersectingKeys
    .ToDictionary(key => key, key => col1[key] + col2[key]);

それがうまく機能するかどうかはわかりませんが、少なくとも読み取り可能です。

于 2011-10-21T12:00:27.800 に答える
1

入力データが次のようになっているとします。

IEnumerable<Tuple<string, int>> firstSequence = ..., secondSequence = ...;

文字列が各シーケンスで一意である場合 (つまり、どちらのシーケンスにも単一の {"A", XXX} しか存在できない場合)、次のjoinようにすることができます。

var query = from tuple1 in firstSequence
            join tuple2 in secondSequence on tuple1.Item1 equals tuple2.Item1
            select Tuple.Create(tuple1.Item1, tuple1.Item2 + tuple2.Item2);

group byこの一意性が保持されない場合は、より適切なa の使用を検討することもできます。

var query = from tuple in firstSequence.Concat(secondSequence)
            group tuple.Item2 by tuple.Item1 into g
            select Tuple.Create(g.Key, g.Sum());

どちらも希望しない場合は、要件をより正確に明確にしてください。

編集:これらが辞書であることを明確にした後、既存のソリューションは完全に問題ありません。を使用した別の代替手段を次に示しjoinます。

var joined = from kvp1 in dict1
             join kvp2 in dict2 on kvp1.Key equals kvp2.Key
             select new { kvp1.Key, Value = kvp1.Value + kvp2.Value };

var result = joined.ToDictionary(t => t.Key, t => t.Value);

または流暢な構文で:

var result = dict1.Join(dict2,
                        kvp => kvp.Key,
                        kvp => kvp.Key,
                        (kvp1, kvp2) => new { kvp1.Key, Value = kvp1.Value + kvp2.Value })
                  .ToDictionary(a => a.Key, a => a.Value);
于 2011-10-21T11:56:48.260 に答える
1

これで結果が得られますが、いくつかの注意点があります。2 つのコレクションを結合してから、それらを文字ごとにグループ化します。したがって、たとえばcol12 つの要素が含まれている場合、Aそれらを合計すると、現在は 2Aであるため、それらが返されます。

var col1 = new[] { new { L = "A", N = 5 }, new { L = "B", N = 3 }, new { L = "C", N = 2 } };
var col2 = new[] { new { L = "B", N = 1 }, new { L = "C", N = 8 }, new { L = "D", N = 6 } };

var res = col1.Concat(col2)
              .GroupBy(p => p.L)
              .Where(p => p.Count() > 1)
              .Select(p => new { L = p.Key, N = p.Sum(q => q.N) })
              .ToArray();
于 2011-10-21T11:56:52.660 に答える
0

交差アルゴリズムが匿名型になる場合、つまり...Select(new { Key = key, Value = value})、簡単に合計できます

result.Sum(e => e.Value);

交差を行っている間を合計したい場合は、結果セットに追加するときにアキュムレータ値に値を追加します。

于 2011-10-21T11:55:15.357 に答える