如果我完全理解你正在嘗試做什麼,那麼我不認爲我會完全依賴於內置的LINQ操作符。我認爲(強調認爲)內置LINQ操作符的任何組合都將在O(n^2)運行時解決這個問題。
如果我打算在LINQ實現這個話,我會給IEnumerable的擴展方法是類似反應擴展的Scan
功能(或找到一個圖書館,在那裏,已經實現了它):
public static class EnumerableExtensions
{
public static IEnumerable<TAccumulate> Scan<TSource, TAccumulate>(
this IEnumerable<TSource> source,
TAccumulate seed,
Func<TAccumulate, TSource, TAccumulate> accumulator)
{
// Validation omitted for clarity.
foreach(TSource value in source)
{
seed = accumulator.Invoke(seed, value);
yield return seed;
}
}
}
那麼這應該做到這一點各地爲O(n log n)的(因爲操作的順序):
leaveDetails
.OrderBy(x => x.LeaveType)
.ThenBy(x => x.Year)
.Scan(new {
Year = 0,
LeaveType = "Seed",
LeaveTaken = 0,
LeaveAllocation = 0.0,
LeaveCarriedOver = 0.0,
RunningTotal = 0.0
},
(acc, x) => new {
x.Year,
x.LeaveType,
x.LeaveTaken,
x.LeaveAllocation,
x.LeaveCarriedOver,
RunningTotal = x.LeaveCarriedOver + (acc.LeaveType != x.LeaveType ? 0 : acc.RunningTotal)
});
你不說,但我相信數據是從數據庫中來;如果是這種情況,那麼你可以得到leaveDetails
已經排序,並跳過這裏排序。這會讓你下降到O(n)。
如果你不想創建一個擴展方法(或去找一個),那麼這將實現相同的事情(只是以一種更醜陋的方式)。
var temp = new
{
Year = 0,
LeaveType = "Who Cares",
LeaveTaken = 3,
LeaveAllocation = 0.0,
LeaveCarriedOver = 0.0,
RunningTotal = 0.0
};
var runningTotals = (new[] { temp }).ToList();
runningTotals.RemoveAt(0);
foreach(var l in leaveDetails.OrderBy(x => x.LeaveType).ThenBy(x => x.Year))
{
var s = runningTotals.LastOrDefault();
runningTotals.Add(new
{
l.Year,
l.LeaveType,
l.LeaveTaken,
l.LeaveAllocation,
l.LeaveCarriedOver,
RunningTotal = l.LeaveCarriedOver + (s == null || s.LeaveType != l.LeaveType ? 0 : s.RunningTotal)
});
}
這也應該是爲O(n log n)的或爲O(n),如果你能預先整理leaveDetails
。
也許你可以使用LINQ的Aggregate方法:https://msdn.microsoft.com/en-us/library/system.linq.enumerable.aggregate.aspx。這相當於函數式編程的一個摺疊。 –
我會給你一些關於如何解決這個問題的提示,你可以通過得到Year('int')和LeaveType(我認爲它是'string')的'distinct''List>'來實現。爲了得到這個,一個簡單的'Distinct <>'後跟一個'Select <>'應該給你。那麼這個清單就是你實際積累的總數。現在使用這個新列表,你需要做一個'Select <>'並且返回一個新的對象,所以可以說'Tuple '其中前2個參數與另一個列表相同,但是最後一個int需要使用'Where'>'過濾year/leavetype的細節列表,然後返回'Sum <>'。 –
Franck
@Franck你的評論對我來說是有意義的,但我只是沒有正確使用我的linq查詢。你可以請實施答覆嗎?謝謝 – mboko