2

我有两个要相交的集合,并对匹配的元素执行求和运算。

例如,集合是(在伪代码中):

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

期望的结果是:

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

我知道如何使用 anIEqualityComparer来匹配其名称上的元素,但是如何在进行交集时对值求和?

编辑:

起始集合没有两个具有相同名称的项目。

4

4 回答 4

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);

您可能还想考虑使用 a group by,如果这种唯一性不成立,这将更合适:

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

这将给出结果,但有一些警告。它将两个集合合并,然后按字母对它们进行分组。因此,例如,如果col1包含两个A元素,它将把它们加在一起,因为现在它们是 2 A,它会返回它们。

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 回答
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 回答
0

如果您的交集算法将导致匿名类型,即...Select(new { Key = key, Value = value})您可以轻松地将其相加

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

如果要对进行交集的“while”求和,请在添加到结果集时将该值添加到累加器值。

于 2011-10-21T11:55:15.357 回答