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.