我有两个班级:
public GeneralClassName
{
public GeneralClassName ()
{
SpecificList = new List<OtherClass>();
}
public string StringValue;
public string OtherStringValue;
public List<OtherClass> SpecificList;
}
和
public OtherClass
{
public string Name;
public string Number;
}
在JSON反序列化之后,我获得了一个很好的List<GeneralClassName>
,我想要的结果是Dictionary<string, int>
,其值是变量的总和&#34; Number&#34;在List<OtherClass>
内的List<GeneralClassName>
内,而键是变量名。
换句话说,我想按名称对数字分组进行总结。
现在,我唯一想到的就是嵌套的foreach,类似的东西:
Dictionary<string, int> resultDictionary = new Dictionary<string, int>();
foreach(List<OtherClass> listOtherClass in bigListGeneralClass.Select(x => x.SpecificList))
{
foreach(OtherClass otherClass in listOtherClass)
{
int value = 0;
if(resultDictionary.ContainsKey(otherClass.Name))
{
resultDictionary[otherClass.Name] += otherClass.Number;
}
else
{
resultDictionary.Add(otherClass.Name, otherClass.Number);
}
}
}
虽然这个解决方案似乎运作良好,但我根本不喜欢它。 有没有更简洁的方法来找到这个结果?也许通过一个很好的LINQ查询?
答案 0 :(得分:6)
由于您未使用GeneralClassName
中的任何信息,因此可以使用SelectMany
展平您的列表。这个OtherClass
个实例的平面列表按Name
属性分组。最后,将组列表转换为字典,其中组的键(也称为Name
属性)是新属性的键,值是所有Number
值的总和。组:
var result = bigListGeneralClass.SelectMany(x => x.SpecificList)
.GroupBy(x => x.Name)
.ToDictionary(x => x.Key,
x => x.Sum(y => y.Number));
此代码假定OtherClass.Number
实际上是int
而不是string
。这个假设也用在带循环的示例代码中
如果此假设不正确,请将y.Number
更改为int.Parse(CultureInfo.InvariantCulture, y.Number)
注意:如果无法解析任何数字,这将抛出异常,因此您可能需要事先确保所有数字都包含有效数字。
答案 1 :(得分:0)
试试这个:
Dictionary<string, int> result =
bigListGeneralClass.SpecificList.GroupBy(sl => sl.Name)
.ToDictionary(group => group.Key, group => group.Sum(x => Int32.Parse(x.Number)));