查询嵌套列表

时间:2012-11-19 15:36:43

标签: c# linq

我有两个班级:

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查询?

2 个答案:

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