Подтвердить что ты не робот

Как обрабатывать нули в LINQ при использовании Min или Max?

У меня есть следующий запрос Linq:

result.Partials.Where(o => o.IsPositive).Min(o => o.Result)

Я получаю исключение, когда result.Partials.Where(o = > o.IsPositive) не содержит элементов. Есть ли элегантный способ справиться с этим иначе, чем разделить операцию на две части и проверить на нуль? У меня есть класс, полный таких операций, как этот.

EDIT: вопрос связан с LINQ to Objects.

Это Исключение, которое я получаю (в переводе сказано: последовательность пуста):

enter image description here

4b9b3361

Ответ 1

Краткий обзор вычисления Min

   var min = result.Partials.Where(o => o.IsPositive).Min(o => o.Result);

Это ваш случай: если нет соответствующих элементов, то вызов Min вызывает исключение (InvalidOperationException).

 var min = result.Partials.Where(o => o.IsPositive)
                          .Select(o => o.Result)
                          .DefaultIfEmpty().Min();

DefaultIfEmpty создаст перечисление над элементом 0, если в списке нет элементов. Как вы знаете, что 0 - это Min или 0 означает список без элементов?

   var min = result.Partials.Where(o => o.IsPositive)
                            .Min(o => (decimal?)o.Result);

Здесь min - либо null (defaul(decimal?)), либо фактическое значение Min. Таким образом, потребитель этого результата будет знать, что если результат равен нулю, то в списке не было элементов, а когда результат равен десятичному значению, то в списке были некоторые элементы, а Min из этих элементов - это значение.

Однако, когда это не имеет значения, тогда можно вызвать min.GetValueOrDefault(0).

Ответ 2

Вы можете использовать метод DefaultIfEmpty, чтобы гарантировать, что коллекция имеет как минимум 1 элемент:

result.Partials.Where(o => o.IsPositive).Select(o => o.Result).DefaultIfEmpty().Min();

Ответ 3

Вы не можете использовать Min (или Max), если последовательность пуста. Если этого не должно быть, у вас другая проблема с тем, как вы определяете result. В противном случае вы должны проверить, является ли последовательность пустой и обрабатывать соответственно, например:

var query = result.Partials.Where(o => o.IsPositve);
min = query.Any() ? query.Min(o => o.Result) : 0; // insert a different "default" value of your choice...    

Ответ 4

Еще один способ выразить это в LINQ - использовать Aggregate:

var min = result.Partials
    .Where(o => o.IsPositive)
    .Select(o => o.Result)
    .Aggregate(0, Math.Min); // Or any other value which should be returned for empty list