E più parametri


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

Quello che mi aspetto è di eseguire questo codice: true && true && false && false e che dovrebbe restituire false .

Come farlo funzionare in js? Grazie


Sto solo esitando. Voglio essere sicuro che la mia idea sia ben formulata. Se esiste un modo migliore, ti preghiamo di suggerire.
Hakim Asa,

Quale dovrebbe essere l'output quando vengono utilizzati i valori Troothy anziché i valori booleani? cioè andMultipleExpr(1, 1, 0, 0)oandMultipleExpr(1, 1, 1, 1)
nick zoum il

Inoltre quale dovrebbe essere l'output di andMultipleExpr()(Chiamare la funzione senza parametri)?
nick zoum,

bene, anche questi casi devono essere presi in considerazione. :-)
Hakim Asa il

Risposte:


16

Utilizzare Array.prototype.everysu tutti gli argomenti passati per verificare se sono tutti veri;

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


Potrebbe sostituire e => e === trueconBoolean
nick zoum il

@nickzoum questo corrisponderebbe a tutti i valori di verità, OP sta confrontando rigorosamente true.
Archie,

1
@Archie - No, stanno confrontando verità / falsità. Non c'è ===nel codice OP. La tua everyidea è perfetta , però. Ma .every(e => e)fa solo il lavoro.
TJ Crowder,

@TJCrowder sì, l'ho appena notato. Ho già aggiornato la risposta. Grazie :)
Archie il

Se aggiungi una funzione di supporto: const isTrue = x => x === true(o x => !!xper tutti i valori di verità), puoi comprimere la tua soluzione return arguments.every(isTrue). Il che per me sembra semplicemente bello.
mbojko,

9

Devi

  1. Inizia con logicalAndimpostato sutrue

  2. Utilizzare logicalAnddurante l'aggiornamento, anziché utilizzare due voci daarguments

Il minimo cambiamento è:

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

Ma la soluzione di mbojko ha il vantaggio di cortocircuitare (fermare il loop quando trova per la prima volta un valore falso), che sembra una buona idea.

Dato che stai usando ES2015 +, probabilmente dovresti usare un parametro rest piuttosto che arguments, e puoi usare un for-ofloop:

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

Puoi anche cortocircuitare questo in linea con l'approccio di mbojko

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

Alcune persone potrebbero lanciarlo reduce, ma la everysoluzione di Archie è molto migliore. (Ma dal momento che il tuo confronto non è rigoroso, lo farei solo .every(flag => flag).)


1
Grazie. Questo ha più senso per me :-)
Hakim Asa, il

In questo caso non è necessario aggiungere un secondo parametro nell'istruzione di riduzione, anche il primo parametro per impostazione predefinita funzionerebbe.
nick zoum,

1
@nickzoum - Solo se possiamo supporre che la funzione non verrà mai chiamata senza argomenti, dal momento che [].reduce((a,b)=>a && b)genera.
TJ Crowder,

6

I resi anticipati dovrebbero rendere il codice più efficiente e più breve:

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

  return true;
}

4

Penso che questo sia un modo molto breve con ES6 Array.prototype.reduce

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

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

Per ulteriori spiegazioni sulla funzione di riduzione, leggere MDN


Se stai facendo utilizzare un metodo array, è molto meglio usare everycome Archie ha fatto rispetto reduce. Più semplice e cortocircuito.
TJ Crowder,

È vero. Ma restiamo ora che vuole, ma LOGICO O || ora con la riduzione, cambierà && in ||
Patrissol Kenfack,

O everya some. Ancora più semplice. Cortocircuito ancora.
TJ Crowder,

Molto bene. Hai ragione @TJCrowder
Patrissol Kenfack il

3

Potresti prendere Array#everye restituire l'ultimo valore.

Questo approccio restituisce il vero risultato di AND logico&& .

Usando l'approccio, viene creato un corto circuito per il primo valore di falsy trovato. Quindi l'iterazione si interrompe.

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

Forse vuoi sentire cosa è andato storto con il loop:

for (i = 0; i < arguments.length; i++){
  logicalAnd =  arguments[i] && arguments[i+1];
}
  1. questo ciclo memorizza gli &&ultimi due oggetti che incontra. Nel caso ideale sarebbero &&insieme gli ultimi due elementi dell'array (che non è già quello di cui hai bisogno)
  2. Inoltre, alla fine del ciclo i=arguments.length-1, controllerà l'ultimo elemento dell'array ed i+1è l'elemento "dopo" l'ultimo, che è undefined. In termini di relazioni logiche, si considera false, ma &&in tal caso produce il valore stesso, ed è per questo che la funzione ritorna undefinedcontinuamente (questo avrebbe potuto essere menzionato nella domanda).

Documenti

expr1 && expr2: Se expr1può essere convertito in true, ritorna expr2; altrimenti, ritorna expr1.

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

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


Invece, dovresti usare logicalAndcome un accumulatore, che raccoglie il risultato di &&-ing tutti gli elementi precedenti e un trucco che puoi usare è se il risultato di un parziale &&è false, non importa quali siano gli elementi rimanenti, il risultato finale lo sarà false, quindi il loop può fermarsi immediatamente:

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

e quindi puoi ottimizzarlo verso la risposta di Archie : il risultato di &&-ing items è truese tutti gli articoli lo sono true, e non devi eseguire una singola &&operazione per calcolare il risultato:

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

(Nei frammenti sopra ho mirato a produrre falseper un elenco di argomenti vuoto.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.