Как использовать LINQ для выбора объекта с минимальным или максимальным значением свойства

В HTML5 были введены методы history.pushState() и history.replaceState() , которые позволяют добавлять и изменять записи истории соответственно.

window.history.pushState('page2', 'Title', '/page2.php');

Подробнее об этом от здесь

416
задан Chris Marisic 12 January 2016 в 20:42
поделиться

5 ответов

People.Aggregate((curMin, x) => (curMin == null || (x.DateOfBirth ?? DateTime.MaxValue) <
    curMin.DateOfBirth ? x : curMin))
282
ответ дан 22 November 2019 в 23:14
поделиться

К сожалению, для этого нет встроенного метода.

PM> Install-Package morelinq

var firstBorn = People.MinBy(p => p.DateOfBirth ?? DateTime.MaxValue);

В качестве альтернативы вы можете использовать реализацию, которую мы получили в MoreLINQ , в MinBy.cs . (Разумеется, существует соответствующий MaxBy .) Вот его суть:

public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source,
    Func<TSource, TKey> selector)
{
    return source.MinBy(selector, null);
}

public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source,
    Func<TSource, TKey> selector, IComparer<TKey> comparer)
{
    if (source == null) throw new ArgumentNullException("source");
    if (selector == null) throw new ArgumentNullException("selector");
    comparer = comparer ?? Comparer<TKey>.Default;

    using (var sourceIterator = source.GetEnumerator())
    {
        if (!sourceIterator.MoveNext())
        {
            throw new InvalidOperationException("Sequence contains no elements");
        }
        var min = sourceIterator.Current;
        var minKey = selector(min);
        while (sourceIterator.MoveNext())
        {
            var candidate = sourceIterator.Current;
            var candidateProjected = selector(candidate);
            if (comparer.Compare(candidateProjected, minKey) < 0)
            {
                min = candidate;
                minKey = candidateProjected;
            }
        }
        return min;
    }
}

Обратите внимание, что это вызовет исключение, если последовательность пуста, и сначала вернет элемент с минимальным значением, если их больше одного.

214
ответ дан 22 November 2019 в 23:14
поделиться
People.OrderBy(p => p.DateOfBirth.GetValueOrDefault(DateTime.MaxValue)).First()

Сработает

60
ответ дан 22 November 2019 в 23:14
поделиться

ИЗМЕНИТЬ снова:

Извините. Помимо отсутствия значения, допускающего значение NULL, я искал не ту функцию,

Min <(Of <(TSource, TResult>)>) (IEnumerable <(Of <(TSource>)>), Func <(Of <(TSource, TResult >)>)) действительно возвращает тип результата, как вы сказали.

Я бы сказал, что одним из возможных решений является реализация IComparable и использование Min <(Of <(TSource>)>) (IEnumerable <(Of <(TSource>)>)) , что действительно возвращает элемент из IEnumerable. Конечно, это не поможет, если вы не можете изменить элемент. Я нахожу здесь дизайн MS немного странным.

Конечно, вы всегда можете выполнить цикл for, если вам нужно, или использовать реализацию MoreLINQ, которую дал Джон Скит.

0
ответ дан 22 November 2019 в 23:14
поделиться

ПРИМЕЧАНИЕ. Я включаю этот ответ для полноты картины, поскольку OP не упомянул источник данных, и мы не должны делать никаких предположений.

Этот запрос дает правильный ответ, но может быть медленнее , поскольку может потребоваться отсортировать все элементы в People , в зависимости от того, какая структура данных People :

var oldest = People.OrderBy(p => p.DateOfBirth ?? DateTime.MaxValue).First();

ОБНОВЛЕНИЕ: На самом деле я не должен называть это решение «наивным», но пользователь действительно должен знать, против чего он запрашивает. «Медленность» этого решения зависит от исходных данных. Если это массив или List , то LINQ to Objects не имеет другого выбора, кроме как сначала отсортировать всю коллекцию перед выбором первого элемента. В этом случае это будет медленнее, чем другое предложенное решение. Тем не мение, если это таблица LINQ to SQL, а DateOfBirth - индексированный столбец, то SQL Server будет использовать индекс вместо сортировки всех строк. Другие пользовательские реализации IEnumerable также могут использовать индексы (см. i4o: Indexed LINQ или базу данных объектов db4o ) и сделать это решение быстрее, чем Aggregate () или MaxBy () / MinBy () , которым необходимо выполнить итерацию всей коллекции один раз. Фактически, LINQ to Objects мог бы (теоретически) создать особые случаи в OrderBy () для отсортированных коллекций, таких как SortedList , но это не так, насколько я знаю.

тогда SQL Server будет использовать индекс вместо сортировки всех строк. Другие пользовательские реализации IEnumerable также могут использовать индексы (см. i4o: Indexed LINQ или базу данных объектов db4o ) и сделать это решение быстрее, чем Aggregate () или MaxBy () / MinBy () , которым необходимо выполнить итерацию всей коллекции один раз. Фактически, LINQ to Objects мог бы (теоретически) создать особые случаи в OrderBy () для отсортированных коллекций, таких как SortedList , но это не так, насколько я знаю.

тогда SQL Server будет использовать индекс вместо сортировки всех строк. Другие пользовательские реализации IEnumerable также могут использовать индексы (см. i4o: Indexed LINQ или базу данных объектов db4o ) и сделать это решение быстрее, чем Aggregate () или MaxBy () / MinBy () , которым необходимо выполнить итерацию всей коллекции один раз. Фактически, LINQ to Objects мог бы (теоретически) создать особые случаи в OrderBy () для отсортированных коллекций, таких как SortedList , но это не так, насколько я знаю.

или базу данных объектов db4o ) и сделайте это решение быстрее, чем Aggregate () или MaxBy () / MinBy () , которые необходимо выполнить итерацию всей коллекции один раз. Фактически, LINQ to Objects мог бы (теоретически) создать особые случаи в OrderBy () для отсортированных коллекций, таких как SortedList , но это не так, насколько я знаю.

или базу данных объектов db4o ) и сделайте это решение быстрее, чем Aggregate () или MaxBy () / MinBy () , которые необходимо выполнить итерацию всей коллекции один раз. Фактически, LINQ to Objects мог бы (теоретически) создать особые случаи в OrderBy () для отсортированных коллекций, таких как SortedList , но это не так, насколько я знаю.

122
ответ дан 22 November 2019 в 23:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: