2010-08-27 7 views
13

J'ai un simple pour la déclaration comme ceci:Comment inverser l'ordre dans une boucle

var num = 10, 
    reverse = false; 

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

lorsque inverse est faux, je veux revenir quelque chose comme [0,1,2,3 , 4,5,6,7,8,9]

mais, quand inverse est vrai, il devrait retourner [9,8,7,6,5,4,3,2,1,0]

Quel est le moyen le plus efficace pour obtenir ce résultat, sans vérifier à chaque fois si re le verset est vrai ou faux dans la boucle?

Je ne veux pas faire:

var num = 10, 
    reverse = false; 

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

Je voudrais vérifier inverse une seule fois en dehors de la boucle.

+1

Qu'essayez-vous vraiment de faire? Parce que si c'est créer un tableau, ou une boucle sur un tableau, il y a toujours la fonction javascript inverse http://www.w3schools.com/jsref/jsref_reverse.asp que vous pouvez appeler – CaffGeek

+1

w3schools n'est pas si bon. Découvrez [w3fools] (http://w3fools.com/). – DwB

Répondre

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:

Comme indiqué dans les commentaires ci-dessous, si i n'est pas déclaré ailleurs et vous ne voulez pas qu'il soit global, puis déclarez avec les autres variables que vous déclaré.

Et si vous ne souhaitez pas modifier la valeur de num, attribuez-le d'abord à 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

Nice. J'allais suggérer 'pour (i = num; i--;) log (i);', mais [le consensus] (http://stackoverflow.com/questions/1340589/javascript-are-loops-really- plus vite en inverse) semble être que votre méthode est la plus rapide. – palswim

+0

Pour l'op: soyez conscient que 'num' sera modifié lors de l'impression en sens inverse, alors assurez-vous de faire une copie de la valeur d'origine si vous prévoyez d'utiliser cette valeur dans le futur. –

+0

@Daniel - Très vrai. Si c'est un problème, voici le remplacement rapide de l'instruction '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

Le 'i <= end' donnera des problèmes ici, car la vérification doit être' i> = 0' à l'envers. –

+2

devrait être i! = Fin – Equiso

+0

Hey c'est vrai. Fixe – Jerome

7

Utiliser 2 boucles:

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

J'étais sur le point de poster à peu près la même chose que cela. Cela me semble la solution la plus naturelle et la plus lisible, et est également efficace, le drapeau inverse est testé une seule fois et pas à chaque fois dans la boucle. – Jay

0

Et quel est votre problème avec:

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

}

+1

Peut-être que dans le code de production il y aura plus de choses à l'intérieur de la boucle qu'un simple 'console.log'? – meagar

+0

@meagar: Si oui, poussez tout dans la boucle dans une fonction. – 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); 
} 

C'est Equival ent à ce qui suit, qui est plus lisible, mais moins compact:

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:
En fait, ces deux solutions ne sont pas identiques, parce que le premier a une opération d'augmentation supplémentaire. Pourtant, il est négligeable du point de vue de la performance. Si vous voulez vraiment obtenir une solution compacte qui a les meilleures performances, vous pouvez faire ce qui suit (pas pour les faibles de cœur):

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

Cela a l'avantage d'avoir une structure de contrôle unique, un seul test dans chaque boucle, et un seul ajout d'itérateur. Ce n'est pas aussi rapide que d'avoir un itérateur incrément/décrément, mais seulement marginalement.

+0

lol. Vous avez écrit le vôtre pendant que j'écrivais le mien (la page était rafraîchie lorsque de nouvelles réponses étaient postées). : P J'abuse des déclarations ternaires. Heureux de voir quelqu'un qui écrit comme moi. – XstreamINsanity

+0

Aucun abus de ternaries là-bas ... Je considère qu'il abuse seulement si vous n'utilisez pas la valeur de retour de l'expression ternaire comme condition? faire quelque chose(): faire quelque choseElse(); --- Complètement à l'extérieur du point, cependant ... –

+0

J'aime votre solution, mais j'ai trouvé l'un plus clair de la patrick. – Raspo

1

Je pense que cela répond à vos besoins:

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 est semblable à la mienne, mais voici ce que je pensais. Je vais vous donner ce que j'ai écrit en C# et comment je pense que cela se traduit par 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); 
    } 

Et voici une autre façon
Javascript

var num = 10, 
     reverse = false; 

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

    } 
+1

Tous ces éléments testent toujours le drapeau inversé à chaque itération de la boucle. – Jay

+0

lol. Mon mauvais, je n'ai pas vu cette partie dans la question. Merci de me le faire savoir. Cependant, pour le PO, si vous êtes inquiet au sujet de la performance, je ne le ferais pas. Je penserai à autre chose si je peux. – XstreamINsanity

+0

Je pense que l'OP n'était pas au courant des instructions ternaires, pensant qu'elles devraient avoir un if/else dans leur boucle. Je pense toujours à une autre façon cependant. – XstreamINsanity

0

Il semble fonctionner:

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

Sûrement dans une langue comme Javascript il doit y avoir un moyen de définir une fonction locale et l'utiliser dans la boucle?

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

Je ne connais pas le format Javascript, mais je ne sais pas quelle forme prendrait la fonction.

1

Voilà comment je l'ai toujours fait des boucles inversées:

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

Vous devriez lire la question avant de répondre;) – yckart

2

Je viens suis tombé sur la nécessité de l'autre jour. Voici comment je l'ai fait:

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

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

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

Pas besoin de boucles distinctes, et pas besoin de faire des mathématiques pour calculer la i appropriée dans la boucle.

Donc, si reverse est true ...

  • i (qui représente notre premier article) devient num - 1, donc nous commençons maintenant sur ce qui aurait été le dernier élément

  • num (qui représente hors limites) devient -1, donc nous nous arrêtons maintenant sur ce qui aurait été le premier élément

  • direction est -1, ce qui signifie qu'il décrémenter quand nous faisons i += direction

Donc en échangeant notre point de départ de notre point de fin et en changeant la modification de i de 1 à -1, nous allons aller vers le haut ou vers le bas en fonction de ces modifications.