Я пишу запрос в Linq, который должен проверить, проходят ли один или несколько элементов в списке предикат A()
, а нет - предикат {{X1} }. Чтобы включить Linq to SQL, нужен один запрос. Итак, для следующих списков результаты должны быть такими, где a
передает предикат A()
, а b
передает предикат B()
:
1. [ a, a ] => true
2. [ a ] => true
3. [ a, b ] => false
4. [ b, b ] => false
5. [ b ] => false
6. [ ] => false
Я пробовал следующее, но у каждого из них есть определенные ситуации, когда они не работают:
// Fails in case 6
MyList.All(x => A(x) && !B(x));
// Fails in case 3
MyList.Where(x => !B(x)).Count(x => A(x)) > 0;
// This works, but it's not a single query anymore
MyList.All(x => A(x) && !B(x)) && Mylist.Count() > 0;
Я чувствую, что мне здесь нужно что-то эквивалентное всем, но которое возвращает false для пустого списка. Например, это будет проходить во всех случаях:
MyList.AllButReturnFalseIfListIsEmpty(x => A(x) && !B(x));
Как я могу этого добиться?
5 ответов
Я бы предложил вам что-то похожее на мой ответ на Linq All в пустой коллекции :
var result = MyList.Max(x => B(x) ? (int?)2 : A(X) ? (int?)1 : (int?)0) == 1;
Он использует принцип работы метода Max<int?>
(A) Если последовательность пуста, она возвращает null
(B) Если существует хотя бы один элемент, соответствующий B, результат будет 2
(C) Если есть хотя бы один элемент, не соответствующий B и соответствующий A, результат будет 1
(D) В противном случае результат будет 0
Итак, мы просто проверим случай (C).
Попробуй это:
MyList.All(x => MyList.Any() && A(x) && !B(x));
Вы не должны использовать All (), если хотите, чтобы он возвращал false для пустой коллекции. Взгляните на документация:
истина, если каждый элемент исходной последовательности проходит проверку в указанный предикат, или если последовательность пуста ; в противном случае - ложь.
Вместо этого я бы попробовал что-то вроде этого:
MyList.Where(x => A(x) && !B(x)).Any();
Почему бы вам просто не проверить, есть ли какой-нибудь предмет после оценки?
MyList.Where(x => A(x) && !B(x)).Any();
Сделать это можно так:
var result = MyList
.Select(x => B(x) ? -1 : (A(x) ? 1 : 0))
.Aggregate(0, (p, v) => v == -1 || p == -1 ? -1 : p + v) > 0;
Запрос работает следующим образом:
Select
производит-1
, когдаB
равноtrue
; в противном случае он производит1
, еслиA
равноtrue
, и0
, еслиA
ложноAggregate
проверяет этот список номеров из-1, 0, 1
. Если он видит-1
, результатом агрегирования будет-1
. В противном случае результатом агрегации является сумма положительных значений.- Сравнение в конце гарантирует, что есть хотя бы один
A
и нетB
s.
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.