![](/img/trans.png)
[英]How to return List of objects containing aggregated (rising) sum of following elements with C# Enumerable.Aggregate method?
[英]C#: How to use the Enumerable.Aggregate method
让我们说我有这个截肢的Person
类:
class Person
{
public int Age { get; set; }
public string Country { get; set; }
public int SOReputation { get; set; }
public TimeSpan TimeSpentOnSO { get; set; }
...
}
然后,我可以像这样分组Age
和Country
:
var groups = aListOfPeople.GroupBy(x => new { x.Country, x.Age });
然后我可以输出所有组的声誉总数如下:
foreach(var g in groups)
Console.WriteLine("{0}, {1}:{2}",
g.Key.Country,
g.Key.Age,
g.Sum(x => x.SOReputation));
我的问题是,如何获得TimeSpentOnSO
属性的总和? Sum
方法在这种情况下不起作用,因为它只适用于int
等。 我以为我可以使用Aggregate
方法,但只是认真无法弄清楚如何使用它...我正在尝试各种组合的各种属性和类型,但编译器只是不会识别它。
foreach(var g in groups)
Console.WriteLine("{0}, {1}:{2}",
g.Key.Country,
g.Key.Age,
g.Aggregate( what goes here?? ));
我是否完全误解了Aggregate方法? 或者发生了什么? 是否应该使用其他方法? 或者我是否必须为TimeSpan
编写自己的Sum
变量?
如果Person是一个匿名类,例如Select
或GroupJoin
语句的结果呢?
刚想通过我可以让Aggregate
方法工作,如果我先在TimeSpan
属性上Select
了...但我发现那种烦人的......还是觉得我根本不懂这个方法......
foreach(var g in groups)
Console.WriteLine("{0}, {1}:{2}",
g.Key.Country,
g.Key.Age,
g.Select(x => x.TimeSpentOnSO)
g.Aggregate((sum, x) => sum + y));
List<TimeSpan> list = new List<TimeSpan>
{
new TimeSpan(1),
new TimeSpan(2),
new TimeSpan(3)
};
TimeSpan total = list.Aggregate(TimeSpan.Zero, (sum, value) => sum.Add(value));
Debug.Assert(total.Ticks == 6);
g.Aggregate(TimeSpan.Zero, (i, p) => i + p.TimeSpentOnSO)
基本上,Aggregate的第一个参数是初始化器,它在第二个参数中传递的函数中用作“i”的第一个值。 它将遍历列表,每次“i”将包含到目前为止的总数。
例如:
List<int> nums = new List<int>{1,2,3,4,5};
nums.Aggregate(0, (x,y) => x + y); // sums up the numbers, starting with 0 => 15
nums.Aggregate(0, (x,y) => x * y); // multiplies the numbers, starting with 0 => 0, because anything multiplied by 0 is 0
nums.Aggregate(1, (x,y) => x * y); // multiplies the numbers, starting with 1 => 120
Chris和Daniels的结合为我解决了这个问题。 我需要初始化TimeSpan,我做错了顺序。 解决方案是:
foreach(var g in groups)
Console.WriteLine("{0}, {1}:{2}",
g.Key.Country,
g.Key.Age,
g.Aggregate(TimeSpan.Zero, (sum, x) => sum + x.TimeSpentOnSO));
谢谢!
而且...... D'哦!
你可以编写TimeSpan
Sum
方法......
public static TimeSpan Sum(this IEnumerable<TimeSpan> times)
{
return TimeSpan.FromTicks(times.Sum(t => t.Ticks));
}
public static TimeSpan Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource, TimeSpan> selector)
{
return TimeSpan.FromTicks(source.Sum(t => selector(t).Ticks));
}
或者, MiscUtil具有通用启用的Sum
方法,因此Sum
应该在TimeSpan
上正常工作(因为定义了TimeSpan+TimeSpan=>TimeSpan
运算符)。
请不要告诉我这个号码......它会吓到我......
您可以总结TimeSpan的Total属性之一。 例如,您可以像这样获得在SO上花费的TotalHours时间:
g.Sum(x => x.SOReputation.TotalHours)
我相信这会给你你正在寻找的结果,但需要注意的是你必须根据你的需要(小时,分钟,秒,天等)设置测量单位。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.