我有数值的列表,每个日期,就像这样:LINQ中的ForEach循环如何知道以前的循环迭代中的值?
Date Value
-------- -----
3/5/2017 2
3/6/2017 2
3/7/2017 3
3/8/2017 3
3/9/2017 3
3/10/2017 4
你可以看到,我们在“2”了两天,然后升级到“3”三天,然后得第四天“4”。
使用LINQ,很容易表现上,我们取得了创纪录的日期:
values.GroupBy(x => x.Value).OrderBy(x => x.Key).ToList().ForEach(x =>
{
var record = x.OrderBy(x1 => x1.Date).First();
Console.WriteLine(
$"New record of {x.Key} on {record.Date.ToShortDateString()}"
);
});
此输出:
New record of 2 on 3/5/2017
New record of 3 on 3/7/2017
New record of 4 on 3/10/2017
这是伟大的,但如果我想这样做的:
New record of 2 on 3/5/2017
New record of 3 on 3/7/2017 (took 2 days)
New record of 4 on 3/10/2017 (took 3 days)
ForEach
循环的每个迭代将要知道最后一个值的值以便计算差异。这将如何成为可能?
答:
答案在下面选择,但这里是用我的实际执行Aggregate
:
values.OrderBy(x => x.Date).Aggregate((a, b) =>
{
if (b.Value > a.Value)
{
$"New record of {b.Value} on {b.Date.ToShortDateString()} (took {b.Date.Subtract(a.Date).Days} day(s))".Dump();
return b;
}
return a;
});
这个结果:
New record of 3 on 3/7/2017 (took 2 day(s))
New record of 4 on 3/10/2017 (took 3 day(s))
注意, “基线” 的2没有在那里列出,这对我的目的来说很好。
Aggregate
的关键在于它可以写成功能性的工作,通过二元组中的枚举 - 两个组中的枚举。因此:
1,2
2,3
3,4
在许多情况下,您将这两件事合并,然后返回组合。但没有任何理由你不能仅仅将与比较,然后返回其中一个。这就是我所做的 - 我比较他们,然后返回新记录,如果它是新记录,否则我返回现有记录。
总结可以帮助你。 https://msdn.microsoft.com/en-us/library/bb549218(v=vs.110).aspx – PlayDeezGames
LINQ似乎并不是解决这个问题的最好方法... – maccettura
您是否尝试将其转换为'查找'而不是'List',然后获取项目数并写入控制台? –