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.