如何使用LINQ查找总和?

24

我有这样一个结构:

private readonly Dictionary<string, Dictionary<string, int>> _storage =
    new Dictionary<string, Dictionary<string, int>>();

关键词: 固件(string): 关键词: 设备(string) : 值 用户总数 (int)

我需要获取每个设备的用户总数,但我真的不知道如何使用LINQ来实现。已经尝试了很多变体。请帮帮我!

目前,我只是用一个完整的函数来实现它

private XlsRow2 GetTotalPerDevice(Dictionary<string, Dictionary<string, int>> storage)
    {
        XlsRow2 totalPerDeviceRow = new XlsRow2();
        totalPerDeviceRow._Name = "Grand Total";
        totalPerDeviceRow.UseBorders = true;
        foreach (var deviceModel in _allDeviceModels)
        {
            foreach (var firmware in storage)
            {
                foreach (var device in firmware.Value)
                {
                    var countOfUsers = 0;
                    if (deviceModel == device.Key)
                    {
                        countOfUsers += device.Value;

                        if (!_totalsPerDevice.ContainsKey(deviceModel))
                        {
                            _totalsPerDevice.Add(deviceModel, countOfUsers);
                        }
                        else
                        {
                            _totalsPerDevice[deviceModel] += countOfUsers;
                        }
                    }
                }
            }
        }
        foreach (var deviceModel in _allDeviceModels)
        {
            if (_totalsPerDevice.ContainsKey(deviceModel))
            {
                totalPerDeviceRow._AddColumn(_totalsPerDevice.First(k => k.Key == deviceModel.ToString()).Value.ToString());
            }
            else
            {
                totalPerDeviceRow._AddColumn("");
            }
        }
        return totalPerDeviceRow;
    }
4个回答

34

比如这个样子?

var result = _storage.SelectMany(x => x.Value)
    .GroupBy(x => x.Key)
    .Select(x => new { Device = x.Key, Total = x.Sum(y => y.Value) });

12

由于要聚合的数据键位于第二级字典中,一个很好的第一步是将所有内部字典中的键值对转储到一个平面序列中。之后你所需要做的就是聚合计数,就像这样:

var res = _storage
    .SelectMany(d => d.Value)
    .GroupBy(kvp => kvp.Key)
    .ToDictionary(g => g.Key, g => g.Sum(kvp => kvp.Value));

再次提醒,最佳答案不一定得分最高,而是已经获得许多投票的答案。抱歉,兄弟。 - MakePeaceGreatAgain

11
一个字典实现了 IEnumerable<KeyValuePair<TKey,TValue>,这意味着您可以在其上使用LINQ。在这种情况下,您有一个字典的字典,并且需要按第二级键进行分组。为此,您需要展平字典,这可以使用 SelectMany 完成。
_storage.Selectmany(pair=>pair.Value);

一旦你拥有了叶级别的条目,你就可以按照它们的键进行分组:

_storage.Selectmany(pair=>pair.Value)
        .GroupBy(leaf=>leaf.Key);

并计算每个组的总和:

var totals=_storage.SelectMany(pair=>pair.Value)
                   .GroupBy(leaf=>leaf.Key)
                   .Select(grp=>new {
                                        Device = grp.Key,
                                        TotalUsers =grp.Sum(leaf=>leaf.Value)
                                    });

等价的查询语句更加简洁:

var totals2 = from frm in _storage
              from dev in frm.Value
              group dev by dev.Key into grp
              select new {
                           Device = grp.Key,
                           Total=grp.Sum(leaf=>leaf.Value)
                         };

给定以下字典:

var _storage = new Dictionary<string, Dictionary<string, int>> {
    ["Frm1"]=new Dictionary<string, int> { 
                    ["Device1"]=4,
                    ["Device2"]=5
                },
    ["Frm2"]=new Dictionary<string, int> { 
                    ["Device1"]=41,
                    ["Device3"]=5
                }                    
};

两个查询返回相同的值

foreach(var total in totals)
{
   Console.WriteLine ($"{total.Device} = {total.Total}");
}
------------------
Device1 = 45
Device2 = 5
Device3 = 5

6
你可以这样做:

你可以像这样做:

Dictionary<string, Dictionary<string, int>> _storage = new Dictionary<string, Dictionary<string, int>>();
Dictionary<string, int> x = new Dictionary<string, int>();
x.Add("x", 2);
x.Add("z", 2);
x.Add("y", 2);
_storage.Add("x", x);
_storage.Add("z", x);
_storage.Add("y", x);

 var b = _storage.SelectMany(keyValuePair => keyValuePair.Value)
         .GroupBy(keyValuePair => keyValuePair.Key)
         .ToDictionary(valuePairs => valuePairs.Key, grouping => grouping.Sum(kvp => kvp.Value));

结果将会像这样: 在这里输入图片描述

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接