Как получить последнюю дату из коллекции объектов с помощью LINQ?
У меня есть список объектов, и каждый объект имеет свойство ExpirationDate, которое имеет тип DateTime. Я хочу получить последнюю дату в списке. Есть ли элегантный способ сделать это через LINQ?
Что-то вроде:
DateTime latestDate = myCollection.Where(r=>r.ExpirationDate.HasValue).MaxDate(r=>r.ExpirationDate.Value);
Ответы
Ответ 1
DateTime? latestDate = myCollection.Max(r => r.ExpirationDate);
Intellisense должен был дать вам метод Max(). =)
Теперь, если вы должны назначить его DateTime, я бы подумал об этом:
DateTime latestDate = myCollection.Where(r => r.ExpirationDate.HasValue)
.Max(r => r.ExpirationDate)
.Value;
Это не будет охватывать случай пустой коллекции или коллекции с нулевыми значениями ExpirationDates.
В зависимости от вашей предыдущей логики, проверяя
myCollection.Any(r => r.ExpirationDate.HasValue)
может быть хорошей идеей, прежде чем пытаться присвоить значение.
Ответ 2
Ты почти там. Используйте Max:
DateTime? biggest = myCollection.Max(r=>r.ExpirationDate);
Если все даты истечения срока действия являются нулевыми или коллекция пуста, в результате вы получите Null, в противном случае - самую большую дату.
Как вы прокомментировали J. Sheens answer, в котором вы хотите использовать DateTime, в результате вам нужно будет что-то сделать с любой пустой коллекцией или без элементов со значением, вы можете сделать это с помощью
DateTime biggest=myCollection.Max(r=>r.ExpirationDate) ?? DateTime.MinValue
Это даст вам DateTime.MinValue
вместо нулей в моем предыдущем примере (у него также есть преимущество перед использованием предложения any
, который он выполняет итерацию коллекции один раз). В качестве примера я выбрал MinValue
. Вы можете использовать свою собственную устаревшую дату.
Использование DateTime? лучше, потому что он позволяет вам использовать значение null для обозначения, которое оно означает: undefined, поскольку MinValue
может быть допустимым элементом в вашем списке.
Ответ 3
Отсортируйте список по дате по убыванию и возьмите первый (проецируя при необходимости).
var latestExpirationDate = myCollection
.Where(item => item.ExpirationDate.HasValue)
.OrderByDescending(item => item.ExpirationDate)
.Select(item => item.ExpirationDate) // DateTime?
.FirstOrDefault();
if (latestExpirationDate != null)
{
// do something with the value stored in latestExpirationDate
}
Как я написал это, у меня создалось впечатление, что метод Max()
работает только с числовыми типами (т.е. int, short, decimal и т.д.). Он также работает с объектами DateTime
. Так что это может сработать:
var expiredItems = myCollection
.Where(item => item.ExpirationDate.HasValue);
if (expiredItems.Any())
{
var latestExpirationDate = expiredItems.Max(item => item.ExpirationDate.Value);
// do something with latestExpirationDate
}
Ответ 4
Просто проверьте, нет ли проверки NullReference перед назначением .ExpriationDate
:
DateTime maxDate = myCollection.OrderByDescending(o => o.ExpirationDate).Take(1).FirstOrDefault().ExpirationDate;
У Бобал была правильная идея с
DateTime maxDate = objL.Max(o => o.ExpirationDate);