我有一个包含日期和值的对象列表。每个日期有一个对象,过去几个月的每个日期都有一个对象。我正在寻找将值更改为最新值的日期。
这是我的意思的一个例子:
<datevalue>
<date>8-9</date>
<value>5</value>
</datevalue>
<datevalue>
<date>8-10</date>
<value>6</value>
</datevalue>
<datevalue>
<date>8-11</date>
<value>5</value>
</datevalue>
<datevalue>
<date>8-12</date>
<value>5</value>
</datevalue>
<datevalue>
<date>8-13</date>
<value>5</value>
</datevalue>
在上面的示例中,当前值为 5,因为它是最近日期 8-13 上的值。我想返回 8-11 日期值对象,因为它是值更改为最新值的那一天。我不想要 8-9 值,因为即使它是当前值的最早日期,但该值在该日期之后发生了更改。
这是我第一次尝试解决这个问题:
DateValue FindMostRecentValueChange(List<DateValue> dateValues)
{
var currentValue = dateValues
.OrderByDesc(d => d.date)
.Select(d => d.value)
.First();
var mostRecentChange = dateValues
.OrderByDesc(d => d.date)
.TakeWhile(d => d.value = currentValue)
.Last();
return mostRecentChange;
}
这行得通。但是,有人向我指出,我正在为这两个操作重复 OrderByDesc。考虑到 OrderByDesc 可能是一项昂贵的操作,我不想做两次。因此我做了一个改变:
DateValue FindMostRecentValueChange(List<DateValue> dateValues)
{
var orderedDateValues = dateValues.OrderByDesc(d => d.date);
var currentValue = orderedDateValues;
.Select(d => d.value)
.First();
var mostRecentChange = orderedDateValues
.TakeWhile(d => d.value = currentValue)
.Last();
return mostRecentChange;
}
现在我只调用 OrderByDesc 一次。这是一种改进,对吧?好吧,也许不是。OrderByDesc 是延迟执行。
据我了解,这意味着在您向其索取价值之前,实际订购并未完成。因此,当您在查找 currentValue 时调用 First() 时执行 OrderByDesc,然后在查找 mostRecentChange 时调用 Last() 时再次执行它。那么这是否意味着我仍在执行 OrderByDesc 两次?
我是否正确解释了延迟执行的运作方式?我希望编译器能够识别这种情况并在幕后对其进行优化,以便只调用一次执行,但我找不到任何信息来支持这一理论。您能帮我了解优化此解决方案的最佳方法吗?