2010-08-27 15 views
13

Tengo un simple para la declaración como esta:Como Invertir el orden en un bucle FOR

var num = 10, 
    reverse = false; 

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

cuando inversa es falso Quiero que vuelva algo como [0,1,2,3 , 4,5,6,7,8,9]

pero, cuando inversa es cierto, debe devolver [9,8,7,6,5,4,3,2,1,0]

Cuál es la forma más eficiente de obtener este resultado, sin verificar siempre si re el verso es verdadero o falso dentro del ciclo?

no quiero hacer esto:

var num = 10, 
    reverse = false; 

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

me gustaría comprobar inversa sólo una vez fuera del bucle.

+1

¿Qué estás tratando de hacer realmente? Porque si se trata de crear una matriz o bucle en una matriz, siempre existe la función de Javascript inversa http://www.w3schools.com/jsref/jsref_reverse.asp, que puedes llamar al – CaffGeek

+1

w3schools no es tan bueno. Consulte [w3fools] (http://w3fools.com/). – DwB

Respuesta

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:

Como se señaló en los comentarios a continuación, si i no se ha declarado en otro lugar y que no tienen la intención de que sea global, entonces declaran que con las otras variables que declarado.

Y si no desea modificar el valor de num, primero, asignelo al 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

Agradable. Iba a sugerir 'para (i = num; i--;) log (i);', pero [el consenso] (http://stackoverflow.com/questions/1340589/javascript-are-loops-really- más rápido en reversa) parece ser que su método es el más rápido. – palswim

+0

Para la operación: tenga en cuenta que 'num' se modificará cuando se imprima en reversa, así que asegúrese de hacer una copia del valor original si planea usar ese valor en el futuro. –

+0

@Daniel - Muy cierto. Si eso es una preocupación, aquí está el reemplazo rápido para la declaración '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

El 'i <= end' dará problemas aquí, ya que la verificación debe ser' i> = 0' en reversa. –

+2

debería ser i! = End – Equiso

+0

Hola, eso es correcto. Corregido – Jerome

7

uso Try 2 bucles:

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

Estaba a punto de publicar más o menos lo mismo que esto. Esta me parece la solución más natural y legible, y también es eficiente, la bandera inversa se prueba una sola vez y no siempre a través del ciclo. – Jay

0

Y lo que es su problema:

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

}

+1

¿Quizás en el código de producción habrá más cosas dentro del circuito que un simple 'console.log'? – meagar

+0

@meagar: Si es así, inserte todo lo que está dentro del bucle en una función. – 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); 
} 

Esta es Equival ent a la siguiente, que es más legible, pero menos compacta:

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

Editar:
En realidad, estas dos soluciones no son idénticos, ya que el primero tiene una operación adicional de incremento. Aún así, es insignificante desde el punto de vista del rendimiento. Si usted realmente desea conseguir una solución compacta que tiene el mejor rendimiento, puede hacer lo siguiente (no para los débiles de corazón):

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

Esto tiene la ventaja de tener una única estructura de control, una sola prueba en cada ciclo, y una sola adición iterador. No es tan rápido como tener un incremento/decremento de iterador, pero solo marginalmente.

+0

lol. Usted escribió el suyo mientras escribía el mío (la página se actualizó cuando se publicaron nuevas respuestas). : P Abuso las declaraciones ternarias. Me alegra ver a alguien que escribe como yo. – XstreamINsanity

+0

No abuso de ternaries allí ... Lo considero abuso solo si no utiliza el valor de retorno de la expresión ternaria como condición? doSomething(): doSomethingElse(); --- Completamente fuera del punto, sin embargo ... –

+0

Me gusta tu solución, pero encontré que el patricio es más claro. – Raspo

1

creo que este se adapte a sus necesidades:

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 es similar a la mía, pero aquí es lo que estaba pensando. Te daré lo que escribí en C# y cómo creo que se traduce en 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); 
    } 

Y aquí es otra forma
Javascript

var num = 10, 
     reverse = false; 

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

    } 
+1

Todos estos aún prueban la bandera inversa en cada iteración del ciclo. – Jay

+0

lol. Mi mal, no vi esa parte en la pregunta. Gracias por hacérmelo saber. Sin embargo, para el OP, si te preocupa el rendimiento, no lo haría. Sin embargo, pensaré en otra cosa, si puedo. – XstreamINsanity

+0

Creo que el OP no estaba al tanto de las declaraciones ternarias, pensando que tendrían que tener un if/else en su ciclo. Todavía estoy pensando en otra manera sin embargo. – XstreamINsanity

0

Parece que funciona:

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

Sin duda, en un lenguaje como Javascript tiene que haber una manera de definir una función local y el uso que en el circuito?

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

Sin embargo, aunque no conozco Javascript, no sé qué forma real tomarían las definiciones de función.

1

Así es como siempre he hecho bucles inversa:

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

Debe leer la pregunta antes de responder;) – yckart

2

me encontré con la necesidad de esto el otro día. He aquí cómo lo hice:

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

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

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

No hay necesidad de bucles separados, y no hay necesidad de hacer matemáticas para calcular el correcto i en el bucle.

Así que si es reverse ... true

  • i (que representa nuestro primer artículo) se convierte en num - 1, por lo que ahora estamos empezando en lo que habría sido el último elemento

  • num (que representa fuera de límites) se convierte en -1, por lo que ahora nos detenemos en lo que habría sido el primer elemento

  • direction es -1, lo que significa que disminuirá cuando hacemos i += direction

Así mediante el canje de nuestro punto de partida con nuestro punto de llegada y el cambio de la alteración de i de 1 a -1, vamos a ir hacia arriba o hacia abajo basado en esas modificaciones

Cuestiones relacionadas