如何使用LINQ查找总和?

时间:2016-12-21 12:08:06

标签: c# linq

我有这个结构:

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

key:Firmware(string):key:Device(string):value CountOfUsers(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 个答案:

答案 0 :(得分:31)

例如这样的东西?

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

答案 1 :(得分:11)

由于您要聚合的数据的键位于二级字典中,因此良好的第一步是将内部字典中的所有键值对转储为平面序列。之后,您只需聚合计数,如下所示:

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

答案 2 :(得分:10)

字典实现var constraints = { audio:true, video:{ deviceId: {exact: devcs[1]} } }; options = { audio : false, localVideo : videoInput, remoteVideo : videoOutput, mediaConstraints:constraints, onicecandidate : onIceCandidate, onerror : onError } ,这意味着您可以在其上使用LINQ。在这种情况下,您有一个词典字典,需要按二级键分组。要做到这一点,您需要展平字典,这可以通过IEnumerable<KeyValuePair<TKey,TValue>

完成
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
                }                    
};

答案 3 :(得分:5)

您可以这样做:

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));

结果如下: enter image description here