我想要一个函数AnyTrue[expr,{i,{i1,i2,...}}]
来检查expr
True
是否为i1,i2...
AnyTrue
Table
Or@@%
expr
True
Table
后跟SetAttributes[AllTrue, HoldAll];
SetAttributes[AnyTrue, HoldAll];
AllTrue[{var_Symbol, lis_List}, expr_] :=
LengthWhile[lis,
TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]] &] ==
Length[lis];
AnyTrue[{var_Symbol, lis_List}, expr_] :=
LengthWhile[lis,
Not[TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]]] &] <
Length[lis];
AllTrue[{a, {1, 3, 5}}, AnyTrue[{b, {2, 4, 5}}, EvenQ[a + b]]]
AnyTrue[{a, {1, 3, 5}}, AllTrue[{b, {2, 4, 5}}, EvenQ[a + b]]]
,区别在于它只会在找到第一个{{1}}之前评估{{1}}。
短路部分是可选的,我真正想知道的是模拟{{1}}非标准评估序列的正确方法。
更新11/14
这是Michael的解决方案,您可以使用它来链接“for all”和“there exists”支票
{{1}}
答案 0 :(得分:5)
这个怎么样?
SetAttributes[AnyTrue, HoldAll];
AnyTrue[expr_, {var_Symbol, lis_List}] :=
LengthWhile[lis,
Not[TrueQ[ReleaseHold[Hold[expr] /. HoldPattern[var] -> #]]] &
] < Length[lis]
通过LengthWhile
包含短路,并在必要时保留所有内容,以便按预期工作,var
的值超出函数范围:
In[161]:= x = 777;
In[162]:= AnyTrue[Print["x=", x]; x == 3, {x, {1, 2, 3, 4, 5}}]
During evaluation of In[162]:= x=1
During evaluation of In[162]:= x=2
During evaluation of In[162]:= x=3
Out[162]= True
内置的Or
也是短路的,因为它的价值。 (但我意识到用例如Table
构建未评估的术语是一种痛苦):
In[173]:= Or[Print[1];True, Print[2];False]
During evaluation of In[173]:= 1
Out[173]= True
答案 1 :(得分:4)
这与您的规范不符,但我经常使用以下实用程序函数,它们与您的想法相似(它们使用纯函数而不是带有指定变量的表达式)并且还会进行短路:
some[f_, l_List] := True === (* Whether f applied to some *)
Scan[If[f[#], Return[True]]&, l]; (* element of list is True. *)
every[f_, l_List] := Null === (* Similarly, And @@ f/@l *)
Scan[If[!f[#], Return[False]]&, l]; (* (but with lazy evaluation). *)
例如,Michael Pilat的例子就是这样:
In[1]:= some[(Print["x=", #]; # == 3)&, {1, 2, 3, 4, 5}]
During evaluation of In[1]:= x=1
During evaluation of In[1]:= x=2
During evaluation of In[1]:= x=3
Out[1]= True