AND çoklu parametreler


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

Ne bekliyorum bu kodu çalıştırmaktır: true && true && false && false ve bu yanlış dönmelidir .

Bunu js'de nasıl çalıştırabilirim? Teşekkürler


Sadece tereddüt ediyorum. Fikrimin iyi formüle edilip edilmediğinden emin olmak istiyorum. Daha iyi bir yol varsa, lütfen önerin.
— Hakim Asa

Boolean yerine Troothy değerleri kullanıldığında çıktı ne olmalıdır? ie andMultipleExpr(1, 1, 0, 0)orandMultipleExpr(1, 1, 1, 1)
— nick zoum

Ayrıca ne olmalıdır andMultipleExpr()(Parametresiz fonksiyonu çağırmak)?
— nick zoum

bu davaların da dikkate alınması gerekiyor. :-)
— Hakim Asa

Yanıtlar:


16

Kullan Array.prototype.everyhepsi doğruysa kontrol etmek tüm geçirilen argümanlar üzerinde;

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


Yerine Could e => e === trueileBoolean
— nick Zoum

@nickzoum bu tüm doğru değerlerle eşleşir, OP kesinlikle karşılaştırır true.
— Archie

1
@Archie - Hayır, gerçekleri / sahteleri karşılaştırıyorlar. ===OP kodunda hayır yok . Sizin everyfikir spot olsa. Ama .every(e => e)iş sadece .
— TJ Crowder

@TJCrowder evet bunu fark etti. Cevabı zaten güncellendi. Teşekkürler :)
— Archie

Bir yardımcı işlev eklerseniz: const isTrue = x => x === true(veya x => !!xtüm doğruluk değerleri için), çözümünüzü sıkıştırabilirsiniz return arguments.every(isTrue). Hangi bana sadece güzel görünüyor.
— mbojko

9

Gerek

  1. İle logicalAndayarlanmış olarak başlayıntrue

  2. logicalAndGüncelleme yaparken iki giriş kullanmak yerine kullanınarguments

Minimum değişiklik:

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

Ancak mbojko'nun çözümü , iyi bir fikir gibi görünen kısa devre (ilk kez bir falsy değeri bulduğunda döngüyü durdurma) avantajına sahiptir.

ES2015 + kullandığınız için, muhtemelen bir rest parametresi argumentskullanmalısınız ve bir for-ofdöngü kullanabilirsiniz :

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

Ayrıca mbojko'nun yaklaşımına uygun olarak kısa devre yapabilirsiniz.

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

Bazı insanlar reducebuna atılabilirevery , ancak Archie'nin çözümü çok daha iyi. (Ama karşılaştırmanız katı olmadığından, sadece yapardım .every(flag => flag).)


1
Teşekkürler. Bu benim için daha mantıklı :-)
— Hakim Asa

Bu durumda reduce deyimine ikinci bir parametre eklemenize gerek yoktur, varsayılan olarak ilk parametrenin alınması da işe yarayacaktır.
— nick zoum

1
@nickzoum - Yalnızca işlevin hiçbir argüman olmadan çağrılmayacağını varsayabilirsek, [].reduce((a,b)=>a && b)atar.
— TJ Crowder

6

Erken iadeler kodu daha verimli ve daha kısa yapmalıdır:

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

  return true;
}

4

Bence bu ES6 kullanmak için çok kısa bir yol Array.prototype.reduce

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

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

Azaltma işlevi hakkında daha fazla açıklama için lütfen MDN'yi okuyun


Bir dizi yöntemi kullanıyorsanız , Archie'nin yaptığı gibi kullanmak çok daha iyidir . Daha basit ve kısa devreler. everyreduce
— TJ Crowder

Bu doğru. Ama şimdi istediği gibi kalalım. MANTIK VEYA || şimdi azalma ile, sadece değişim olacak && için ||
— Patrissol Kenfack

Ya everyiçin some. Hala daha basit. Hala kısa devreler.
— TJ Crowder

Aferin. Haklısın @TJCrowder
— Patrissol Kenfack

3

Array#everySon değeri alıp iade edebilirsiniz .

Bu yaklaşım, mantıksal AND'in&& gerçek sonucunu döndürür .

Yaklaşım kullanılarak, ilk bulunan falsy değeri için kısa devre yapılır. Sonra yineleme durur.

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

Belki de döngüde neyin yanlış gittiğini duymak istersiniz:

for (i = 0; i < arguments.length; i++){
  logicalAnd =  arguments[i] && arguments[i+1];
}
  1. bu döngü &&karşılaştığı son iki öğeyi saklar . İdeal durumda &&, dizinin son iki öğesini birlikte kullanırsınız (bu zaten ihtiyacınız olan şey değildir)
  2. bunun üstünde, döngünün sonunda i=arguments.length-1, dizinin son öğesini kontrol eder ve sonuncusu olan i+1"after" elemanıdır undefined. Mantıksal ilişkiler açısından düşünülür false, ancak &&böyle bir durumda değerin kendisini üretir ve bu nedenle işlev undefinedher zaman geri döner (bu soruda belirtilebilirdi).

Dokümanlar

expr1 && expr2: Eğer expr1dönüştürülebilirse true, döndürür expr2; yoksa geri döner expr1.

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

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


Bunun yerine, logicalAndbir &&önceki öğelerin tamamının sonucunu toplayan bir akümülatör olarak kullanmalısınız ve kullanabileceğiniz bir hile, kısmi bir sonuç &&ise false, kalan öğelerin ne olduğu önemli değil, sonuç olacak false, böylece döngü hemen durabilir:

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

ve bunu Archie'nin cevabına göre optimize edebilirsiniz : &&-ing öğelerinin sonucu, truetüm öğelerin olması trueve &&sonucu hesaplamak için tek bir işlem yürütmeniz gerekmemesidir :

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

(Yukarıdaki pasajlarda falseboş bir argüman listesi oluşturmayı amaçladım .)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.