通过中间映射将字典分组到其他字典

Posted

技术标签:

【中文标题】通过中间映射将字典分组到其他字典【英文标题】:Group dictionary to other dictionary via intermediate map 【发布时间】:2021-09-20 19:35:52 【问题描述】:

我有一个在某些键之间映射的字典

var map = new Dictionary<string, string>() "A", "One", "B", "One", "C", "Two" ;

我还有一本包含值的字典

var values = new Dictionary<string, double>()  "A", 2.0, "B", 1.0, "C", 1.0 ;

我想将这些值映射到第三个字典中,以便 map 的值是新字典的键。 IE。我希望新字典是

var result = new Dictionary<string, double>() "One", 3.0, "Two", 1.0;

这当然可以使用这样的循环来实现

var result = new Dictionary<string, double>();
foreach (var kv in values)

    var key = map[kv.Key];
    var value = kv.Value;

    if (result.TryGetValue(key, out var temp))
        result[key] = value + temp;
    else
        result.Add(key, value);

或者类似的东西......

但是是否可以使用 linq 在单行中做到这一点?

【问题讨论】:

为什么需要一行中的linq?在此之后的任何情况下,编译器都会将其转换为一组 for each 循环,这些循环有时可能很难看。最好为每个循环自己制作,特别是如果代码很关键。 好吧,我不需要一行中的 linq。我正在尝试在编写代码时学习一些 linq,而这个问题是我无法弄清楚的。我当前的代码是您建议的使用 for 循环的函数。 它工作正常吗? 我相信它是......我想我知道你要问这个问题了:) 是的,你是对的。最好的人是善的敌人。有瑕疵的钻石好过没有瑕疵的鹅卵石。 【参考方案1】:

试试这个,

var result = map
 .Join(values, x => x.Key, y => y.Key, (x, y) => (x.Value, y.Value))
 .GroupBy(x => x.Item1)
 .ToDictionary(x => x.Key, y => y.Sum(s => s.Item2));

DotNet 小提琴:https://dotnetfiddle.net/tWd9j5

【讨论】:

【参考方案2】:

看起来你正在寻找 Join 方法

var result = map.Join(values, x => x.Key, y => y.Key, (x, y) => (x.Value, y.Value)).ToDictionary(x => x.Item1, y => y.Item2);

并处理重复值

var result = map
            .Join(values, x => x.Key, y => y.Key, (x, y) => (x.Value, y.Value))
            .GroupBy(x => x.Item1)
            .ToDictionary(x => x.Key, y => y.First().Item2);

【讨论】:

嗨,您的代码似乎不起作用...我收到错误“System.ArgumentException:'已添加具有相同密钥的项目。密钥:一个”' 这是因为 map 包含重复值。要处理重复,您只需对其稍作修改 我知道值重复。如果您查看我发布的代码,您会看到我是如何处理它的。您的代码没有产生正确的答案...看来您没有对重叠值求和。但它很接近:)【参考方案3】:

当然可以。

var result = (from m in map
                      join v in values
                      on m.Key equals v.Key
                      group v.Value by m.Value into sameVal
                      select new  MValue = sameVal.Key, VValue = sameVal.Sum() ).ToDictionary(a => a.MValue, b => b.VValue);

【讨论】:

嗨。我知道地图重复了其中一个值。应该是这样的。 您不能使用重复值作为键。从逻辑上讲,它应该是每个值的唯一键。 这一切我都知道。如果您查看我发布的代码,您会发现您需要对这些值求和。 现在我明白你的问题了。编辑了答案 是的。现在它的工作。谢谢 Bazil。

以上是关于通过中间映射将字典分组到其他字典的主要内容,如果未能解决你的问题,请参考以下文章

Python: 字典列表: 通过某个字段将记录分组

Python通过多个键单向分组和聚合字典列表

通过映射到字典创建新列(字符串包含匹配)

python字典

如何通过创建字典从python中的以下映射访问城市名称

学不会的python之通过某几个关键字排序分组一个字典列表(列表中嵌套字典)