簡體   English   中英

C#:如何使用Enumerable.Aggregate方法

[英]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; }

    ...
}

然后,我可以像這樣分組AgeCountry

    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是一個匿名類,例如SelectGroupJoin語句的結果呢?


剛想通過我可以讓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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM