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


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.