聚合多个词典,一起添加值

时间:2016-11-20 00:18:38

标签: c#

是否有更有效的方法将多个词典聚合为一个,如果有一个重复的键,那么将这些值一起添加?字典至少有10000个键值对。

Dictionary<string, int>[] res;
Dictionary<string, int> aggregatedRes = res[0];
for (int i = 1; i < res.Length; i++)
{
    foreach (KeyValuePair<string, int> valuePair in res[i])
    {
        if (aggregatedRes.ContainsKey(valuePair.Key))
        {
            aggregatedRes[valuePair.Key] += valuePair.Value;
        }
        else
        {
            aggregatedRes.Add(valuePair.Key, valuePair.Value);
        }
    }
}

我在stackoverflow上发现了很多关于类似问题的帖子,但是如果有一个重复的键,他们只删除它的一个值,这对我不利。

Dictionary 1
apple - 2
an - 1
I - 1
like - 3

Dictionary 2
apple - 3
car - 1
green - 1

Dictionary 3
apple - 1
green - 1
like - 1

Expected result:
apple - 6
an - 1
I - 1
like - 4
car - 1
green - 2

2 个答案:

答案 0 :(得分:1)

我没有看到任何比你正在做的更好的神奇方式。 (使用LINQ的任何技巧都不会提高性能。)稍微改进可能是按如下方式更改循环:

for (int i = 1; i < res.Length; i++)
{
    foreach (KeyValuePair<string, int> valuePair in res[i])
    {
        int value;
        aggregatedRes.TryGetValue(valuePair.Key, out value);
        aggregatedRes[valuePair.Key] = value + valuePair.Value;
    }
}

如果没有别的,那就更短了。

如果我们只能在aggregatedRes上进行一次查找,那真正有用的是什么,但我认为没办法做到这一点。

答案 1 :(得分:0)

尚未测试性能,但使用linq的 方式是将字典(selectmany)展平,对所有键进行分组并创建新字典,对组值进行求和:

var aggregatedRes  = (from d in res
            from kv in d 
            group kv by kv.Key)
        .ToDictionary(g=>g.Key, g=>g.Sum(kv=>kv.Value));

(对于使用大型词典的表现,上述内容也适用于并行性,使用from d in res.AsParallel()