日付と値を含むオブジェクトのリストがあります。日付ごとに 1 つのオブジェクトと、過去数か月のすべての日付のオブジェクトがあります。値が最新の値に変更された日付を探しています。
これが私が意味することの例です:
<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>
上記の例では、最新の日付である 8 ~ 13 日の値であるため、現在の値は 5 です。値が最新の値に変更された日なので、8-11 の datevalue オブジェクトを返したいです。現在の値で最も早い日であっても、その日付の後に値が変更されたため、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 はコストのかかる操作になる可能性があることを考慮して、2 回実行する必要がないようにしたいと考えました。したがって、私は変更を加えました:
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 を 1 回だけ呼び出します。改善ですね。まあ、そうではないかもしれません。OrderByDesc は遅延実行です。
私が理解していることから、それは、実際の注文は、値を要求するまで行われないことを意味します。したがって、currentValue を探しているときに First() を呼び出すと、OrderByDesc が実行され、mostRecentChange を探しているときに Last() を呼び出すと、もう一度実行されます。ということは、まだ OrderByDesc を 2 回実行しているということですか?
遅延実行がどのように機能するかを正しく解釈していますか? コンパイラがこのシナリオを認識し、実行が 1 回だけ呼び出されるように舞台裏で最適化してくれることを願っていますが、この理論を裏付ける情報が見つかりません。このソリューションを最適化するための最善の方法について頭を悩ませるのを手伝ってもらえますか?