【问题标题】: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 循环的函数。
  • 它工作正常吗?
  • 我相信它是......我想我知道你要问这个问题了:)
  • 是的,你是对的。最好的人是善的敌人。有瑕疵的钻石好过没有瑕疵的鹅卵石。

标签: c# linq dictionary


【解决方案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。
    猜你喜欢
    • 2019-02-23
    • 2015-01-15
    • 2015-10-17
    • 2018-07-18
    • 2015-07-12
    • 1970-01-01
    • 2018-08-26
    • 2023-02-10
    • 1970-01-01
    相关资源
    最近更新 更多