ET plusieurs paramètres


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

Ce que j'attends, c'est d'exécuter ce code: true && true && false && false et cela devrait retourner false .

Comment faire fonctionner ça en js? Merci


J'hésite juste. Je veux être sûr que mon idée est bien formulée. S'il existe une meilleure solution, veuillez suggérer.
— Hakim Asa

Quelle devrait être la sortie lorsque les valeurs Troothy sont utilisées à la place des booléens? soit andMultipleExpr(1, 1, 0, 0)ouandMultipleExpr(1, 1, 1, 1)
— nick zoum

De plus, quelle devrait être la sortie de andMultipleExpr()(Appel de la fonction sans paramètres)?
— nick zoum le

eh bien, ces cas doivent également être pris en compte. :-)
— Hakim Asa

Réponses:


16

Utilisez Array.prototype.everytous les arguments passés pour vérifier s'ils sont tous vrais;

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


Pourrait remplacer e => e === trueparBoolean
— Nick Zoum

@nickzoum, cela correspondrait à toutes les valeurs véridiques, OP compare strictement true.
— Archie

1
@Archie - Non, ils comparent vérité / fausse. Il n'y a pas ===dans le code OP. Mais votre everyidée est parfaite . Mais fait juste .every(e => e)le travail.
— TJ Crowder

@TJCrowder oui vient de le remarquer. Déjà mis à jour la réponse. Merci :)
— Archie

Si vous ajoutez une fonction d'assistance: const isTrue = x => x === true(ou x => !!xpour toutes les valeurs véridiques), vous pouvez compresser votre solution dans return arguments.every(isTrue). Ce qui me semble tout simplement magnifique.
— mbojko

9

Tu dois

  1. Commencez par logicalAnddéfinir surtrue

  2. À utiliser logicalAndlors de la mise à jour, plutôt que d'utiliser deux entrées dearguments

Le changement minimal est:

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

Mais la solution de mbojko a l'avantage de court-circuiter (arrêter la boucle lorsqu'elle trouve une valeur falsifiée pour la première fois), ce qui semble être une bonne idée.

Puisque vous utilisez ES2015 +, vous devriez probablement utiliser un paramètre de repos plutôt que arguments, et vous pouvez utiliser une for-ofboucle:

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

Vous pouvez également court-circuiter cela conformément à l'approche de mbojko

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

Certaines personnes pourraient y jeter un coup reduced'œil, mais la everysolution d'Archie est bien meilleure. (Mais comme votre comparaison n'est pas stricte, je le ferais .every(flag => flag).)


1
Merci. Cela a plus de sens pour moi :-)
— Hakim Asa

Il n'est pas nécessaire d'ajouter un second paramètre dans l'instruction de réduction dans ce cas, obtenir le premier paramètre par défaut fonctionnerait également.
— nick zoum le

1
@nickzoum - Seulement si nous pouvons supposer que la fonction ne sera jamais appelée sans arguments, car [].reduce((a,b)=>a && b)throws.
— TJ Crowder

6

Les retours anticipés devraient rendre le code à la fois plus efficace et plus court:

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

  return true;
}

4

Je pense que c'est un moyen très court d' utiliser ES6 Array.prototype.reduce

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

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

Pour plus d'explications sur la fonction de réduction, veuillez lire MDN


Si vous faites d'utiliser une méthode de tableau, il est bien préférable d'utiliser everycomme Archie a fait que reduce. Plus simple, et ça court-circuite.
— TJ Crowder

C'est vrai. Mais restons maintenant, il veut mais OU LOGIQUE || maintenant avec la réduction, ce sera juste changer && à ||
— Patrissol Kenfack

Ou everypour some. Encore plus simple. Toujours des courts-circuits.
— TJ Crowder

Bien joué. Vous avez raison @TJCrowder
— Patrissol Kenfack

3

Vous pouvez prendre Array#everyet renvoyer la dernière valeur.

Cette approche renvoie le résultat réel d'un ET logique&& .

En utilisant l'approche, un court-circuit est effectué pour la première valeur de falsification trouvée. Ensuite, l'itération s'arrête.

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

Peut-être que vous voulez entendre ce qui a mal tourné avec la boucle:

for (i = 0; i < arguments.length; i++){
  logicalAnd =  arguments[i] && arguments[i+1];
}
  1. cette boucle stocke les &&deux derniers éléments rencontrés. Dans le cas idéal, il &&regrouperait les deux derniers éléments du tableau (ce qui n'est déjà pas ce dont vous avez besoin)
  2. en plus de cela à la fin de la boucle i=arguments.length-1, il vérifiera le dernier élément du tableau, et i+1est l'élément "après" le dernier, qui est undefined. En termes de relations logiques, il est considéré false, mais &&produit la valeur elle-même dans ce cas, et c'est pourquoi la fonction revient undefinedtout le temps (cela aurait pu être mentionné que dans la question).

Documents

expr1 && expr2: Si expr1peut être converti en true, retourne expr2; sinon, revient expr1.

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

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


Au lieu de cela, vous devez utiliser logicalAndcomme accumulateur, qui recueille le résultat de &&-ing tous les éléments précédents, et une astuce que vous pouvez utiliser est que si le résultat d'un partiel &&est false, peu importe ce que sont les éléments restants, le résultat final va être false, donc la boucle peut s'arrêter immédiatement:

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

et ensuite vous pouvez l'optimiser vers la réponse d'Archie : le résultat des &&éléments -ing est truesi tous les éléments le sont true, et vous n'avez pas à exécuter une seule &&opération pour calculer le résultat:

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

(Dans les extraits ci-dessus, je visais à produire falseune liste d'arguments vide.)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.