我有这个结构:
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;
}
答案 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));