我在Linq编写一个查询,需要检查列表中的一个或多个项是否传递谓词A()
,无传递谓词{ {1}}。它需要是单个查询才能启用Linq to SQL。因此,对于以下列表,结果应如下B()
通过谓词a
和A()
传递谓词b
:
B()
我尝试了以下方法,但每种方法都有某些失败的情况:
1. [ a, a ] => true
2. [ a ] => true
3. [ a, b ] => false
4. [ b, b ] => false
5. [ b ] => false
6. [ ] => false
我觉得我需要的东西是等同于all的东西,但是对于空列表返回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;
我怎样才能做到这一点?
答案 0 :(得分:2)
你可以这样做:
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
。答案 1 :(得分:1)
我建议您使用类似于我对Linq All on empty collection的回答:
unset($_SESSION['user']['login'];)
它利用了var result = MyList.Max(x => B(x) ? (int?)2 : A(X) ? (int?)1 : (int?)0) == 1;
方法的工作原理
(A)如果序列为空,则返回Max<int?>
(B)如果至少有一个元素与B匹配,则结果为null
(C)如果至少有一个元素与B匹配且匹配A,则结果为2
(D)否则结果为1
所以我们简单检查案例(C)。
答案 2 :(得分:0)
试试这个:
MyList.All(x => MyList.Any() && A(x) && !B(x));
答案 3 :(得分:0)
为什么不在评估后检查是否有任何项目?
MyList.Where(x => A(x) && !B(x)).Any();
答案 4 :(得分:0)
如果您希望它为空集合返回false,则不应使用All()。看看documentation:
如果源序列的每个元素都通过了测试,则为true 指定的谓词,如果序列为空则 ;否则,错误。
相反,我会尝试这样的事情:
MyList.Where(x => A(x) && !B(x)).Any();