2010-08-27 13 views
13

Ho un semplice PER dichiarazione come questa:Come per invertire l'ordine in un ciclo FOR

var num = 10, 
    reverse = false; 

for(i=0;i<num;i++){ 
    console.log(i); 
} 

quando invertire è falso che voglio per tornare qualcosa di simile [0,1,2,3 , 4,5,6,7,8,9]

ma, quando inverso è vero, dovrebbe restituire [9,8,7,6,5,4,3,2,1,0]

Quale è il modo più efficace per ottenere questo risultato, senza verificare ogni volta se re il versetto è vero o falso all'interno del ciclo?

io non voglio fare questo:

var num = 10, 
    reverse = false; 

for(i=0;i<num;i++){ 
    if(reverse) console.log(num-i) 
    else console.log(i) 
} 

Vorrei verificare inverso solo una volta al di fuori del ciclo.

+1

Cosa stai cercando di fare? Perché se si crea un array, o si esegue il ciclo su un array, c'è sempre la funzione javascript reverse http://www.w3schools.com/jsref/jsref_reverse.asp che puoi chiamare – CaffGeek

+1

w3schools non è così buono. Dai un'occhiata a [w3fools] (http://w3fools.com/). – DwB

risposta

18
var num = 10, 
reverse = false; 

if(!reverse) for(var i=0;i<num;i++) log(i); 
else   while(num--)  log(num); 

    // to avoid duplication if the code gets long 
function log(num) { console.log(num); } 

EDIT:

Come notato nei commenti qui sotto, se i non viene dichiarato altrove e non si intende per essere globale, allora dichiareremo con le altre variabili che si dichiarato.

E se non si desidera modificare il valore di num, quindi assegnarlo prima a i.

var num = 10, 
reverse = false, 
i; 

if(!reverse) for(var i=0;i<num;i++) log(i); // Count up 
else   {var i=num; while(i--) log(i);} // Count down 

function log(num) { console.log(num); } 
+0

Bello. Stavo per suggerire 'for (i = num; i--;) log (i);', ma [il consenso] (http://stackoverflow.com/questions/1340589/javascript-are-loops-really- più veloce al contrario) sembra essere il metodo più veloce. – palswim

+0

Per l'operazione: si tenga presente che 'num' verrà modificato quando verrà stampato al contrario, quindi assicuratevi di fare una copia del valore originale se pensate di usare quel valore in futuro. –

+0

@Daniel - Molto vero. Se questo è un problema, ecco la rapida sostituzione dell'istruzione 'else':' else {i = num; while (i -) log (i)}; ' – user113716

3
var start; var end; var inc; 
if (reverse) { 
    start = num-1; end = 0; inc = -1; 
} 
else { 
    start = 0; end = num-1; inc = 1; 
} 
for(i=start;i!=end;i+=inc){ 
    console.log(i) 
} 
+5

Il 'i <= end' fornirà problemi qui, dal momento che il controllo deve essere' i> = 0' al contrario. –

+2

dovrebbe essere i! = End – Equiso

+0

Ehi, giusto. Fixato – Jerome

7

uso Prova 2 loop:

if (reverse) { 
    for(i=num-1;i>=0;i--){ 
     console.log(i) 
    } 
} 
else { 
    for(i=0;i<num;i++){ 
     console.log(i) 
    } 
} 
+2

Stavo per pubblicare praticamente la stessa cosa di questo. Questa mi sembra la soluzione più naturale e leggibile, ed è anche efficiente, la bandiera inversa viene testata solo una volta e non tutte le volte attraverso il ciclo. – Jay

0

E qual è il tuo problema con:

if (reverse) 
    { 
    for(i=num-1; i>=0;i--){ 
      console.log(i); 
     } 
    } 
    else 
    { 
     for(i=0;i<num;i++){ 
     console.log(i) 
     } 
    } 

}

+1

Forse nel codice di produzione ci saranno più cose all'interno del ciclo che un semplice 'console.log'? – meagar

+0

@meagar: in tal caso, spingere tutto all'interno del loop in una funzione. – Jay

6
var num = 10, 
    reverse = false; 

for (var i = 0, n = reverse?num-1:0, d = reverse?-1:1; i < num; i++, n+=d) { 
    console.log(n); 
} 

Questo è Equival ent di seguito, che è più leggibile, ma meno compatta:

var num = 10, 
    reverse = false; 

var start = reverse ? num-1 : 0, 
    end = reverse ? -1 : num, 
    step = reverse ? -1 : 1; 
for (var i = start; i != end; i += step) { 
    console.log(i); 
} 

Edit:
realtà, queste due soluzioni non sono identici, perché la prima ha un'operazione di incremento aggiuntivo. Tuttavia, è trascurabile dal punto di vista delle prestazioni. Se davvero si vuole ottenere una soluzione compatta che ha le migliori prestazioni, è possibile effettuare le seguenti operazioni (non per i deboli di cuore):

var num = 10, 
    reverse = false; 

for (var r=reverse, i=r?num-1:0, n=r?-1:num, d=r?-1:1; i!=n; i+=d) { 
    console.log(i); 
} 

Questo ha il vantaggio di avere un'unica struttura di controllo, un singolo test in ogni ciclo e una singola aggiunta di iteratore. Non è veloce come avere un incremento/decremento di un iteratore, ma solo marginalmente.

+0

lol. Hai scritto il tuo mentre stavo scrivendo il mio (la pagina è stata aggiornata quando sono state pubblicate nuove risposte). : P abuso di dichiarazioni ternarie. Sono contento di vedere qualcuno che scrive come me. – XstreamINsanity

+0

Nessun abuso di ternari lì ... Lo considero un abuso solo se non si utilizza il valore restituito dell'espressione ternaria come condizione? doSomething(): doSomethingElse(); --- Completamente al di fuori del punto, però ... –

+0

Mi piace la tua soluzione, ma ho trovato quello del patrick più chiaro. – Raspo

1

penso che questo soddisfi le vostre esigenze:

var num = 10; 
var reverse = false; 
var diff = 0; 

if (reverse) { 
    diff = num - 1; 
} 

for (i = 0; i < num; i++) { 
    console.log(Math.abs(diff - i)); 
} 
0

Roy è simile alla mia, ma qui è quello che stavo pensando. Ti darò quello che ho scritto in C# e come penso che si traduca in Javascript.

C#

int num = 10; 
    bool reverse = true; 

    for (int i = reverse ? num : 0; (reverse ? 0 : i) < (reverse ? i : num); i += reverse ? -1 : 1) 
    { 
     Console.Write((reverse ? i - 1 : i).ToString()); 
    } 
    Console.ReadKey(); 

Javascript

 var num = 10, 
     reverse = true; 

    for (int i = reverse ? num : 0; (reverse ? 0 : i) < (reverse ? i : num); i += reverse ? -1 : 1) 
    { 
     console.log(reverse ? i - 1 : i); 
    } 

Ed ecco un altro modo
Javascript

var num = 10, 
     reverse = false; 

    for (int i = 0; i < num; i++) 
    { 
     console.log((reverse ? abs(-num + (i + 1)) : i)); 

    } 
+1

Tutti questi continuano a testare la bandiera inversa su ogni iterazione del ciclo. – Jay

+0

lol. Il mio male, non ho visto quella parte nella domanda. Grazie per avermi fatto sapere. Tuttavia, per l'OP, se sei preoccupato per le prestazioni, non lo farei. Penserò a qualcos'altro, se posso. – XstreamINsanity

+0

Penso che il PO non fosse a conoscenza di dichiarazioni ternarie, pensando che avrebbero dovuto avere un if/else nel loro ciclo. Sto ancora pensando a un altro modo però. – XstreamINsanity

0

Sembra funzionare:

var num = 10; 
    var z = 1; 
    var k = -10; 
    if (reverse){ 
    k = -1; 
    z = -1; 
    } 
    for(int i = 0; i < 10; i++){ 
    console.log(num+i*z+k); 
    } 
0

Sicuramente in un linguaggio come JavaScript ci deve essere un modo per definire una funzione locale e l'uso che nel ciclo?

function SubtractFrom(val, subtractor) { 
    return val - subtractor; 
} 

function PassThrough(val) { 
    return val; 
} 

var num = 10; 
var processor = reverse ? SubtractFrom(num-1) : PassThrough; 

for (i = 0; i < num; i++) { 
    console.log(processor(i)); 
} 

Non sapendo Javascript, però, non so quale forma effettiva richiederebbero le definizioni di funzione.

1

Ecco come ho sempre fatto loop inverso:

for (i = num; --i >= 0;) ... 
+0

Dovresti leggere la domanda prima di rispondere;) – yckart

2

Ho appena incontrato la necessità di questo l'altro giorno. Ecco come ho fatto:

var num = 10, 
    i = 0, 
    direction = 1, 
    reverse = false; 

if(reverse) 
    i = num + (direction = num = -1); 

for(; i !== num; i += direction) { 
    console.log(i); 
} 

Non c'è bisogno di cicli separati, e non c'è bisogno di fare matematica per calcolare la corretta i nel ciclo.

Quindi, se reverse è true ...

  • i (che rappresenta la nostra prima voce) diventa num - 1, così ora stiamo iniziando a quello che sarebbe stato l'ultimo elemento

  • num (che rappresenta fuori limite) diventa -1, quindi ci fermeremo ora su quello che sarebbe stato il primo articolo

  • direction è -1, il che significa che diminuirà quando facciamo i += direction

Così scambiando il nostro punto di partenza con il nostro punto di arrivo e cambiando l'alterazione del i da 1 a -1, andremo verso l'alto o verso il basso in base a tali modifiche.