И несколько параметров - PullRequest
15 голосов
/ 15 января 2020
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 ? Спасибо

Ответы [ 6 ]

16 голосов
/ 15 января 2020

Используйте 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
9 голосов
/ 15 января 2020

Вам необходимо

  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 имеет преимущество короткого замыкания (остановка l oop, когда он впервые находит ложное значение), которое выглядит как хорошая идея.

Поскольку вы используете ES2015 +, вам, вероятно, следует использовать параметр отдыха, а не arguments, и вы можете использовать for-of l oop:

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

Вы также можете замкнуть накоротко, что в соответствии с подходом Мбойко

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

Некоторые люди могут бросить reduce в это, но Arch ie every решение намного лучше. (Но поскольку ваше сравнение не является строгим, я бы просто сделал это .every(flag => flag).)

6 голосов
/ 15 января 2020

Ранний возврат должен сделать код более эффективным и коротким:

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

  return true;
}
4 голосов
/ 15 января 2020

Я думаю, что это очень короткий путь с использованием ES6 Array.prototype.reduce

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

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

Подробнее о функции уменьшения читайте в MDN

3 голосов
/ 15 января 2020

Возможно, вы хотите услышать, что пошло не так с l oop:

for (i = 0; i < arguments.length; i++){
  logicalAnd =  arguments[i] && arguments[i+1];
}
  1. этот l oop хранит && из последних двух предметы, с которыми он сталкивается. В идеальном случае это будет && вместе два последних элемента массива (что уже не то, что вам нужно)
  2. поверх этого в конце l oop 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 в качестве аккумулятора, который собирает результат && -из всех предыдущих элементов, и хитрость того, что вы Можно использовать, если результат частичного && равен false, не имеет значения, что представляют собой остальные элементы, конечный результат будет false, поэтому l oop может немедленно остановиться:

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));

и затем вы можете оптимизировать его до Arch ie s answer : результат && -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 для пустого списка аргументов.)

3 голосов
/ 15 января 2020

Вы можете взять Array#every и вернуть последнее значение.

Этот подход возвращает реальный результат логического И &&.

Используя этот подход, создается короткое замыкание для первого найденного ложного значения. Затем итерация останавливается.

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));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...