І кілька параметрів


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, який повинен повернути помилковий .

Як змусити цю роботу в js? Дякую


Я просто вагаюся. Я хочу бути впевненим, чи добре сформульована моя ідея. Якщо є кращий спосіб, будь ласка, підкажіть.
Хакім Аса

Яким повинен бути вихід, коли значення Troothy використовуються замість булевих? тобто andMultipleExpr(1, 1, 0, 0)абоandMultipleExpr(1, 1, 1, 1)
нік зум

Також яким повинен бути вихід andMultipleExpr()(Виклик функції без параметрів)?
нік зум

ну і ці випадки потрібно також враховувати. :-)
Хакім Аса

Відповіді:


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 === trueзBoolean
ника zoum

@nickzoum це відповідало б усім правдивим значенням, OP суворо порівнює true.
Арчі

1
@Archie - Ні, вони порівнюють правду / хибність. У ===коді ОП немає. Ваша everyідея не впізнається . Але просто .every(e => e)виконує роботу.
TJ Crowder

@TJCrowder так просто це помітив. Відповідь уже оновлено. Дякую :)
Арчі

Якщо ви додасте функцію помічника: const isTrue = x => x === true(або x => !!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 +, ви , ймовірно , слід використовувати параметр спокою , а не 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 набагато краще. (Оскільки ваше порівняння не є суворим, я б просто зробив це .every(flag => flag).)


1
Дякую. Це має для мене більше сенсу :-)
Хакім Аса

У цьому випадку не потрібно додавати другий параметр у оператор зменшення, також отримання першого параметра за замовчуванням також буде працювати.
нік зум

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

Це правда. Але залишимось зараз він хоче, але ЛОГІЧНИЙ АБО || тепер із зменшенням, це буде просто зміна && на ||
Патріссол Кенфак

Або everyдо some. Ще простіше. Ще коротке замикання.
TJ Crowder

Молодці. Ви праві @TJCrowder
Патріссол Кенфак

3

Ви можете взяти 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));


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 всіх попередніх елементів, і хитрість, яку ви можете використовувати, якщо результат часткового &&є 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));

а потім ви можете оптимізувати його в сторону Арчі відповіді : результат &&-ву елементів є , 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створити порожній список аргументів.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.