与多个参数


15
function andMultipleExpr(){
  let logicalAnd;
  let i;
  for (i = 0; i < arguments.length; i++){
    logicalAnd =  arguments[i] && arguments[i+1];
  }
  return logicalAnd;
}

console.log(andMultipleExpr(true, true, false, false));

我期望执行此代码:true && true && false && false,并且应该返回false

如何使它在js中工作?谢谢


我只是在犹豫。我想确定我的想法是否正确制定。如果有更好的方法,请提出建议。
哈基姆·阿萨

当使用Troothy值而不是布尔值时,输出应该是什么?即andMultipleExpr(1, 1, 0, 0)andMultipleExpr(1, 1, 1, 1)
nick zoum

andMultipleExpr()(不带参数调用函数)的输出也应该是什么?
尼克·祖姆

好吧,这些情况也需要考虑在内。:-)
Hakim Asa

Answers:


16

使用Array.prototype.every上的所有传递的参数检查,如果他们都是真实的;

function andMultipleExpr(...a) {
  if(a.length === 0) return false; // return false when no argument being passed
  return a.every(Boolean);
}

console.log(andMultipleExpr(true, true, false)); // should return false
console.log(andMultipleExpr(true, true, true)); // should return true


可以替换e => e === trueBoolean
nick zoum

@nickzoum这将匹配所有真实值,OP严格比较true
阿奇

1
@Archie-不,他们在比较真实/虚假。===OP的代码中没有任何内容。你的every想法是当场上,虽然。但是工作就.every(e => e)完成了。
TJ Crowder

@TJCrowder是的,只是注意到了这一点。已更新答案。谢谢:)
阿奇

如果添加了辅助函数:(const isTrue = x => x === truex => !!x所有真值),则可以将解决方案压缩为return arguments.every(isTrue)。在我看来,这只是美丽。
mbojko

9

你需要

  1. logicalAnd设置为开始true

  2. logicalAnd更新时使用,而不是使用来自两个条目arguments

最小的更改是:

function andMultipleExpr(){
    let logicalAnd = true; // ***
    let i;
    for (i = 0; i < arguments.length; i++){
        logicalAnd = logicalAnd && arguments[i]; // ***
    }
    return logicalAnd;
}
console.log(andMultipleExpr(true, true, false, false));

但是mbojko的解决方案具有短路的优势(在第一次发现虚假值时停止循环),这似乎是个好主意。

由于您使用的是ES2015 +,因此您可能应该使用rest参数而不是arguments,并且可以使用for-of循环:

function andMultipleExpr(...flags) {
    let logicalAnd = true;
    for (const flag of flags) {
        logicalAnd = logicalAnd && flag;
    }
    return logicalAnd;
}
console.log(andMultipleExpr(true, true, false, false));

您也可以按照mbojko的方法进行短路

function andMultipleExpr(...flags) {
    for (const flag of flags) {
        if (!flag) {
            return false;
        }
    }
    return true;
}
console.log(andMultipleExpr(true, true, false, false));

有人可能会reduce对此表示怀疑every,但是Archie的解决方案要好得多。(但由于您的比较并不严格,所以我会做到.every(flag => flag)。)


1
谢谢。这对我来说更有意义:-)
哈基姆·阿萨

在这种情况下,无需在reduce语句中添加第二个参数,默认情况下也可以获取第一个参数。
尼克·祖姆

1
@nickzoum-仅当我们可以假设函数不会因为[].reduce((a,b)=>a && b)抛出参数而没有参数时被调用。
TJ Crowder

6

尽早返回应该使代码既高效又短:

function andMultipleExpr() {
  for (let i = 0; i < arguments.length; i++) {
    if (!arguments[i]) {
      return false;
    }
  }

  return true;
}

4

我认为这是使用ES6的很短的方法 Array.prototype.reduce

let andMultipleExpr = (...args) => args.reduce((a, b) => a && b);

console.log(andMultipleExpr(true, true, false, false));

有关减少功能的更多说明,请阅读MDN


如果你正在做使用一个阵列的方法,这是很多更好地使用every阿奇做reduce。更简单,而且短路。
TJ Crowder

是真的。但是,让我们现在就留下吧,他想,但是逻辑还是|| 现在,随着减少,将&&更改为||。
Patrissol Kenfack

还是everysome。更简单。仍然短路。
TJ Crowder

做得好。您是对的@TJCrowder
Patrissol Kenfack

3

您可以获取Array#every并返回最后一个值。

此方法返回逻辑AND&&的真实结果。

通过使用该方法,对第一个发现的虚假值进行短路。然后迭代停止。

function andMultipleExpr(...args) {
    var result; // any return value is configurable for empty args
    args.every(v => result = v);
    return result;
}

console.log(andMultipleExpr(true, true, false, false));
console.log(andMultipleExpr(true, true, 1, 2));
console.log(andMultipleExpr(true, 0, 1, 2));


3

也许您想听听循环出了什么问题:

for (i = 0; i < arguments.length; i++){
  logicalAnd =  arguments[i] && arguments[i+1];
}
  1. 此循环存储&&它遇到的最后两个项目。在理想情况下,它将&&最后两个元素放在一起(这已经不是您所需要的)
  2. 在循环末尾的最上面i=arguments.length-1,它将检查数组的最后一个元素,并且i+1是最后一个元素“之后”的元素undefined。就逻辑关系而言,它被认为是false,但&&在这种情况下会自己产生值,这就是为什么函数undefined始终返回的原因(在问题中可能已经提到了这一点)。

文件

expr1 && expr2:如果expr1可以转换为true,则返回expr2; 否则,返回expr1

arr=[true];
console.log("your case:",arr[0] && arr[1]);

console.log("1 && 2:", 1 && 2);


相反,您应该将其logicalAnd用作累加器,该累加器收集对&&所有先前元素进行-ing 运算的结果,并且可以使用的技巧是,如果partial的结果&&false,那么剩下的元素是什么都没有关系,最终结果将会是false,因此循环可以立即停止:

function andMultipleExpr(){
    let logicalAnd = arguments[0] || false;
    for (let i = 1; i < arguments.length && logicalAnd; i++){
        logicalAnd = logicalAnd && arguments[i];
    }
    return logicalAnd;
}

console.log("():",andMultipleExpr());
console.log("(false):",andMultipleExpr(false));
console.log("(true):",andMultipleExpr(true));
console.log("(true,true):",andMultipleExpr(true,true));
console.log("(true, true, false, false):",andMultipleExpr(true, true, false, false));

然后可以针对Archie的答案对其进行优化:&&-ing项目的结果是true如果所有项目均为true,则不必执行单个&&操作即可计算结果:

function andMultipleExpr(){
    if(arguments.length===0){
      return false;
    }
    for (let i = 0; i < arguments.length; i++){
      if(!arguments[i]){
        return false;
      }
    }
    return true;
}

console.log("():",andMultipleExpr());
console.log("(false):",andMultipleExpr(false));
console.log("(true):",andMultipleExpr(true));
console.log("(true,true):",andMultipleExpr(true,true));
console.log("(true, true, false, false):",andMultipleExpr(true, true, false, false));

(在上面的代码段中,我旨在生成false一个空的参数列表。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.