簡體   English   中英

如何使用 C# Enumerable.Aggregate 方法返回包含以下元素的聚合(上升)總和的對象列表?

[英]How to return List of objects containing aggregated (rising) sum of following elements with C# Enumerable.Aggregate method?

我有 ObjectA 類,其屬性稱為Value

我還有一個名為Sum的 ObjectB 類。

然后我有 List<ObjectA> listA。

如何從 C# Enumerable.Aggregate 方法返回 List<ObjectB> listB,其中每個后續 ObjectB 的屬性總和是來自 List<ObjectA> 的屬性的(上升)聚合總和?

預期行為:

IN:具有以下屬性的 ObjectA 列表 Value {1,2,3,4,5,6}

OUT:具有以下屬性的 ObjectB 列表 Sum {1,3,6,10,15,21}

簡短的回答:不要。 請改用 Select 或循環。

長答案:

Aggregate適用於您從值列表開始但希望以單個值結束的情況。 您試圖以另一個集合結束,每個輸入都有一個值。

這並不是說它不能完成。 僅出於學術目的,讓我們看一下您可以使用的一些模式。 我打算將問題簡化為只使用整數而不是ObjectAObjectB

這可能是最“純粹”的方法,因為您傳遞給 Aggregate 的委托沒有副作用。

var values = new[]{1,2,3,4,5,6};
var sums = values.Aggregate(Enumerable.Empty<int>(), (previous, next) => previous.Append(previous.LastOrDefault() + next)).ToList();

但是,這可能具有O(n²)復雜性,因為您在通過Append調用鏈接在一起構造的IEnumerable<>上調用LastOrDefault() 最好通過關閉運行總變量來接受一點雜質。

var values = new[]{1,2,3,4,5,6};
int runningTotal = 0;
var sums = values.Aggregate(Enumerable.Empty<int>(), (previous, next) => previous.Append(runningTotal += next)).ToList();

但是,如果我們願意以這種方式跟蹤狀態,那么只需使用Select而不是Aggregate ,事情就會簡單得多:

int runningTotal = 0;
var sums = values.Select(next => runningTotal += next).ToList();

當然,純粹主義者會說像 LINQ 語句這樣的函數式語法不應該有副作用。 只構建一個具有更命令式的 foreach 循環的新列表可能會更清楚。

var values = new[]{1,2,3,4,5,6};
var sums = new List<int>();
int runningTotal = 0;
foreach(var next in values)
{
    runningTotal += next;
    sums.Add(runningTotal);
}

您可以通過以下方式進行Aggregate

var objectBs = objectAs
    .Aggregate<ObjectA, IEnumerable<ObjectB>>(
        Enumerable.Empty<ObjectB>(), 
        (objectBs, objectA) => objectBs.Append(new ObjectB
        {
            Sum = (objectBs.LastOrDefault()?.Sum ?? 0) + objectA.Value
        }));

但這對人們來說很難閱讀(我個人就是這樣)。 或者,用 for 循環編寫它:

var listOfObjectBs = new List<ObjectB>
{
    new ObjectB
    {
        Sum = objectAs.First().Value
    }
};

for (var i = 1; i < objectAs.Count; i++)
{
    listOfObjectBs.Add(new ObjectB
    {
        Sum = listOfObjectBs[i - 1].Sum + objectAs[i].Value
    });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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