Итак, вы последовательность MyClass
объектов и объект X
, и вы хотите найти новейший MyClass
объект, значение которого для Status
равно X
var result = myList.Where(myItem => myItem.Status == X)
.OrderByDescending(myItem => myItem.Date)
.FirstOrDefault();
Хотя это будет работать, сортировка не очень эффективна: после того, как вы найдете первый элемент, он сортирует 2-й, 3-й и т. Д., Хотя вы знаете, что они не будут использовать эти другие элементы, так зачем их сортировать?Если вы используете Aggregate
, вам нужно будет только перечислить один раз
var result = myList.Where(...)
.Aggregate( (newestItem, nextItem) => (newestItem.Date < nextItem.Date) ?
newestItem : nextItem);
Это помещает первый элемент в newestItem и сканирует остальную часть списка.Если какой-либо nextItem имеет новые данные, поместите этот следующий элемент в newestItem, в противном случае не изменяйте newestItem.В конце верните newestItem, который с самой новой датой, которую вы хотите.
Это работает, только если вы уверены, что есть хотя бы один оставшийся элемент после где.Если он также должен работать с пустыми списками, рассмотрите возможность создания функции расширения:
static TResult GetNewestOrDefault<TSource, TResult>(this IEnumerable<TSource> source,
Func<Tsource, DateTime> dateSelector)
{
var enumerator = source.GetEnumerator();
if (enumerator.MoveNext())
{ // at least one element; initialize newest:
TSource newestElement = enumerator.Current;
DateTime newestDate = dateSelector(newest);
// scan the rest of the sequence and check if newer:
while (enumerator.MoveNext())
{
Tsource nextElement = enumerator.Current;
Datetime nextDate = dateSelector(nextElement);
// if next element has a newer date, remember it as newest:
if (newestDate < nextDate
{
newestElement = nextElement;
newestDate = nextDate,
}
}
// scanned all elements exactly once
return newestElement;
}
else
// empty sequence, return default
return default(TResult);
}
Использование:
MyClass result = myList.Where(myItem => myItem.Status == X)
.GetNewestOrDefault();
Это будет сканировать вашу последовательность ровно один раз.