2

我知道 && 和 || 的部分 编写更高效的代码,因为它们在链中执行最少数量的测试,并且一旦我们有足够的信息知道链的结果将是什么,它们就会立即爆发。

  • 一旦 && 在链中命中 FALSE,它就会停止评估并为整个链返回 FALSE。
  • 尽快|| 在链中命中 TRUE 它停止评估并为链返回 TRUE

但是我在 Garrett Grolemund 的书中读到“......双运算符并不适合任何地方。&& 和 || 没有向量化,这意味着它们只能在运算符的每一侧处理一个逻辑测试......”有人可以请向我解释强调的部分是什么意思?

是否进行了一些简单的测试,而 & 正在两个逻辑向量的相应元素之间进行元素比较, && 仅比较第一个元素并返回 TRUE,因为运算符未进行矢量化?是上面所有强调的部分的意思,还是还有更多的意思?

c(T, F, F, F, F) & c(T, T, F, T, F)
[1]  TRUE FALSE FALSE FALSE FALSE

c(T, F, F, F, F) && c(T, T, F, T, F)
[1] TRUE

c(F, F, F, F, F) && c(T, T, F, T, F)
[1] FALSE

any使用and将运算符两侧的向量折叠为一个布尔值all

any(T, T, F, F, T) && all(F, F, T, T, T)
[1] FALSE

any(T, T, F, F, T) && any(F, F, T, T, T)
[1] TRUE
4

1 回答 1

6

他们只能在操作员的每一侧处理一个逻辑测试

a <- c(T, F, F, F)
b <- c(T, F, F, F)
a && b

返回 [1] 真

因为只测试了aand的第一个元素b

编辑:

考虑以下情况,我们在每次测试a后“旋转”:b&&

a <- c(T, F, T, F)
b <- c(T, F, F, T)
for (i in seq_along(a)){
  cat(paste0("'a' is: ", paste0(a, collapse=", "), " and\n'b' is: ", paste0(b, collapse=", "),"\n"))
  print(paste0("'a && b' is: ", a && b))
  a <- c(a[2:length(a)], a[1])
  b <- c(b[2:length(b)], b[i])
}

给我们:

'a' is: TRUE, FALSE, TRUE, FALSE and
'b' is: TRUE, FALSE, FALSE, TRUE
[1] "'a && b' is: TRUE"
'a' is: FALSE, TRUE, FALSE, TRUE and
'b' is: FALSE, FALSE, TRUE, TRUE
[1] "'a && b' is: FALSE"
'a' is: TRUE, FALSE, TRUE, FALSE and
'b' is: FALSE, TRUE, TRUE, FALSE
[1] "'a && b' is: FALSE"
'a' is: FALSE, TRUE, FALSE, TRUE and
'b' is: TRUE, TRUE, FALSE, TRUE
[1] "'a && b' is: FALSE"

此外, &&,||一旦表达式清晰就停止:

FALSE & a_not_existing_object
TRUE | a_not_existing_object

回报:

Error: object 'a_not_existing_object' not found
Error: object 'a_not_existing_object' not found

但:

FALSE && a_not_existing_object
TRUE || a_not_existing_object

回报:

[1] 错误

[1] 对

因为AND之后的任何东西(和OR的东西)分别变成andFALSE TRUE FALSETRUE

如果你想在你的控制流中检查一个可能不存在的元素,那么最后一个行为&&和特别有用:||

if (exists(a_not_existing_object) && a_not_existing_object > 42) {...}

这样,在第一个表达式评估为之后评估停止FALSE并且该a_not_existing_object > 42部分甚至没有被尝试!

于 2020-02-14T07:36:33.763 回答