代码之家  ›  专栏  ›  技术社区  ›  Ben Hymers

组合键匹配的键值对列表

  •  1
  • Ben Hymers  · 技术社区  · 14 年前

    我有一张单子 List<KeyvaluePair<DateTime, int>> ,我想合并成一个(union),如果在多个列表中有具有相同键的对,则求和它们的值。

    例子:

    input list 1:
    date1, 1
    date2, 2
    
    input list 2:
    date2, 3
    date3, 4
    
    input list 3:
    date3, 5
    date4, 6
    
    desired output:
    date1, 1
    date2, 5
    date3, 9
    date4, 6
    

    从我所读到的关于LINQ欺骗的内容来看,这类事情确实可以做得很整齐,但到目前为止,我还没能完全理解。如果有一个很好的方法来处理LINQ,我很乐意听,如果没有,我会很感激其他任何看起来整洁的答案-我的C++大脑只能考虑冗长的程序性方法:

    请注意,我使用列表是有原因的,因此请不要建议使用字典或其他数据类型。谢谢。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Amy B    14 年前
    ILookup<DateTime, int> lookup = source
      .SelectMany(list => list)
      .ToLookup(kvp => kvp.Key, kvp => kvp.Value);
    

    List<KeyValuePair<DateTime, int>> result = source
      .SelectMany(list => list)
      .GroupBy(kvp => kvp.Key, kvp => kvp.Value)
      .Select(g => new KeyValuePair<DateTime, int>(g.Key, g.Sum()))
      .ToList();
    
        2
  •  3
  •   Kobi    14 年前
    var sums = list1.Concat(list2).Concat(list3)
                .GroupBy(pair => pair.Key, pair => pair.Value)
                .ToDictionary(g => g.Key, g => g.Sum());
    

    这里是一个 Dictionary<DateTime, int> ,您可以使用 sums[date] . 要保留当前的数据结构,可以将ToDictionary替换为:

    .Select(g => new KeyValuePair<DateTime, int>(g.Key, g.Sum())).ToList();
    

    更一般的LINQ方法是使用 ILookup -这类似于列表字典,因此如果需要,您可以获取单独的数字(同样,您可以快速转换以获取所需的列表):

    ILookup<DateTime,int> sums = list1.Concat(list2).Concat(list3)
        .ToLookup(pair=>pair.Key,pair=>pair.Value);
    int number = sums[date].Sum();
    
        3
  •  2
  •   Vidar Nordnes    14 年前