У меня есть массив классов со свойством Date
, т.е.:
class Record
{
public DateTime Date { get; private set; }
}
void Summarize(Record[] arr)
{
foreach (var r in arr)
{
// do stuff
}
}
Я должен найти earliest
(минимум) и latest
(максимальные) даты в этом массиве.
Как я могу сделать то использование LINQ?
Если вы хотите найти самую раннюю или новейшую дату:
DateTime earliest = arr.Min(record => record.Date);
DateTime latest = arr.Max(record => record.Date);
enumerable.min , enumerable.max
Если вы хотите найти запись с самым ранним или последняя дата:
Record earliest = arr.MinBy(record => record.Date);
Record latest = arr.MaxBy(record => record.Date);
см.: Как использовать LINQ для выбора объекта с минимальным или максимальным значением свойства
Раствор старого школы без Линка:
DateTime minDate = DateTime.MaxValue;
DateTime maxDate = DateTime.MinValue;
foreach (var r in arr)
{
if (minDate > r.Date)
{
minDate = r.Date;
}
if (maxDate < r.Date)
{
maxDate = r.Date;
}
}
Использование выражений лямбда:
void Summarise(Record[] arr)
{
if (!(arr == null || arr.Length == 0))
{
List<Record> recordList = new List<Record>(arr);
recordList.Sort((x,y) => { return x.Date.CompareTo(y.Date); });
// I may have this the wrong way round, but you get the idea.
DateTime earliest = recordList[0];
DateTime latest = recordList[recordList.Count];
}
}
по сути:
Обновление: Думая об этом, я не уверен, что это способ сделать это, если вы заботитесь вообще о производительности, так как сортировка всего списка приведет к многим другим сравнениям, чем просто сканирование для самых высоких / самых низких значений.
Я бы просто сделал два свойства Min,Max, присвоил им значение первого добавляемого элемента массива, а затем каждый раз при добавлении нового элемента просто проверял, меньше или больше ли его DateTime, чем Min Max.
Это красиво и быстро, и это будет намного быстрее, чем итерация по массиву каждый раз, когда вам нужно получить Min Max.
Два в одном запросе LINQ (и один обход):
arr.Aggregate(
new { MinDate = DateTime.MaxValue,
MaxDate = DateTime.MinValue },
(accDates, record) =>
new { MinDate = record.Date < accDates.MinDate
? record.Date
: accDates.MinDate,
MaxDate = accDates.MaxDate < record.Date
? record.Date
: accDates.MaxDate });