2012-11-19 98 views
1

我有两个类:查询嵌套列表

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>,其值是的总和List<GeneralClassName>内的List<OtherClass>内的变数“数字”,而关键是变数名称。

换句话说,我想按名称对数字进行分组。现在

,跨我的脑海里传来的唯一事情是一个嵌套的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查询?

+1

什么otherClass.count?你的意思是otherClass.Number? –

+0

当我第一次写这个问题时,我使用了一个不同的变量名。然后在阅读文本时,我发现使用“计数”令人困惑。你发现的那个必须滑倒:|对于错误感谢,并感谢编辑。 – Abaco

回答

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)
注意:如果任何数字无法解析,这将引发异常,因此您可能需要事先确定所有数字都包含有效数字。

0

试试这个:

Dictionary<string, int> result = 
      bigListGeneralClass.SpecificList.GroupBy(sl => sl.Name) 
           .ToDictionary(group => group.Key, group => group.Sum(x => Int32.Parse(x.Number))); 
+0

这不起作用,因为'List '没有'SpecificList'成员。 –

+0

@DanielHilgarth bigListGeneralClass不是GeneralClassName的列表,它只是GeneralClassName类型的对象。 –

+0

@DanielHilgarth对不起,我很粗心。 'bigListGeneralClass.SelectMany(l => l.SpecificList).GroupBy(sl => sl.Name) .ToDictionary(group => group.Key,group => group.Sum(x => Int32.Parse(x .Number)));' 这是更正后的版本。 –