【问题标题】:Linq groupBy, Sum and orderByLinq groupBy、Sum 和 orderBy
【发布时间】:2014-06-17 23:04:34
【问题描述】:

这里还在学习 Linq。所以我有一个看起来像这样的类(来自一个 db 表):

class FundRaisingData
{
public double funds { get; set; }
public DateTime date { get; set; }
public string agentsGender { get; set; }
}

我需要做的是将它转换为看起来像这样的匿名对象列表(稍后它将被转换并返回为 JSON)。我知道这不是一个匿名对象,但它会让您对我正在尝试做的事情有所了解:

class groupedFunds
{
public string gender { get; set; }
public List<double> fundsRaised { get; set; }
}

因此,我需要弄清楚如何以正确的顺序(2010-2014 年)汇总每年的资金。

最终它在 JSON 中应该是这样的:

ListOfGroupedFunds[
{
"gender" : "Female",
"fundsRaised" : [2000, 2500, 3000]
},
{
"gender" : "Male",
"fundsRaised": [4300,2300,3100]
}
];

因此,fundsRaised[0] 对应于 2012,fundsRaised[1] 对应于 2013 等等,但实际上在对象中的任何位置都没有说“2013”​​。

我今天在 Linq 上阅读了大量文章并搜索了类似的 StackOverflow 文章,但我仍然无法完全弄清楚。任何能指引我正确方向的帮助都会很棒。

-- 编辑2(更改代码更匹配解决方案)--

我认为 Mike 的代码运行良好,但因为我不确定提前多少年,所以我稍微修改了一下:

var results = data.GroupBy(g=> Gender = g.agentsGender)
              .Select(g=> new 
                          { 
                             gender = g.Key  
                             years = g.GroupBy(y=> y.Date.Year)
                                      .OrderBy(y=> y.Key)
                                      .Select(y=> y.Sum(z=> z.funds))
                                      .ToArray()
                          })
              .ToArray();

上面有什么问题吗?它似乎有效,但我当然愿意接受更好的解决方案。

【问题讨论】:

    标签: c# json linq sum


    【解决方案1】:

    查询任意年数只是您性别组中的另一个子GroupBy()

    var results = data.GroupBy(g=> Gender = g.agentsGender)
                      .Select(g=> new 
                                  { 
                                     gender = g.Key  
                                     years = g.GroupBy(y=> y.Date.Year)
                                              .OrderBy(y=> y.Key)
                                              .Select(y=> y.Sum(y.funds))
                                              .ToArray()
                                  })
                      .ToArray();
    

    【讨论】:

    • 每年的数据索引如何保证?
    • 您只需使用OrderBy() 对您的组键进行排序,这样最早的年份就会排在第一位。
    • 如果一年组里没有数据怎么办?
    • 这是 OP 的要求吗?
    • 不,这不是必需的。我可以(并且需要)在单独的查询中提取这些数据。但实际上它确实要求我在一个单独的数据结构中按顺序提取年份。
    【解决方案2】:

    Thins LINQ 语句将按性别分组,然后将每年的资金总和作为列表。

    var query = from d in data
                group d by d.agentsGender into g
                select new { gender = g.Key, fundsRaised = new List<double> {
                    g.Where(f => f.date.Year == 2012).Sum(f => f.funds),
                    g.Where(f => f.date.Year == 2013).Sum(f => f.funds),
                    g.Where(f => f.date.Year == 2014).Sum(f => f.funds),
                }};
    

    【讨论】:

    • 谢谢迈克!如果我不知道自己还有多少年呢?
    • 这变得更加复杂,因为年份是通过固定长度数组中的位置来推断的。例如,如果您的数据没有 2013 年的数据,但有 2012 年和 2014 年的数据,则 group by 将仅返回 2 个元素。所以基本上为了确保固定的数组大小,必须以某种方式指定年份,因为它总是可以从数据中推断出来。如果您没有在 linq 中指定年份,则必须在某处进行。我希望这是有道理的。如果您可以更改您的数据结构以包括年份和总和,这会简单得多。
    • 所以你是说创建一个带有年份的数据结构并已经在其中求和,然后使用不同的操作来提取我正在寻找的数据?我一直在玩它,我想我可能已经找到了我正在寻找的解决方案,感谢您的帮助。我将在解决方案中发布代码
    猜你喜欢
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    • 2016-06-17
    • 1970-01-01
    相关资源
    最近更新 更多