Linq与sum相交

时间:2011-10-21 11:42:27

标签: linq intersect

我想要交叉两个集合,并对匹配元素执行求和操作。

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

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

,所需的结果是:

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

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

编辑:

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

4 个答案:

答案 0 :(得分: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,如果此唯一性不成立则更合适:

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

答案 1 :(得分: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();

答案 2 :(得分:1)

我想到的最好的是(我的馆藏实际上是Dictionary<string, int>个实例):

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

我不确定它是否会表现良好,至少是否可读。

答案 3 :(得分:0)

如果您的交集算法会产生匿名类型,即...Select(new { Key = key, Value = value}),那么您可以很容易地将其加总

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

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