2010-08-27 2 views
13

Я просто для заявления, как это:Как изменить порядок в цикле

var num = 10, 
    reverse = false; 

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

когда обратного ложен Я хочу, чтобы вернуть что-то вроде [0,1,2,3 , 4,5,6,7,8,9]

но, когда обратный это правда, он должен возвратить [9,8,7,6,5,4,3,2,1,0]

Какой самый эффективный способ получить этот результат, не проверяя каждый раз, если re verse истинно или ложно внутри цикла?

Я не хочу, чтобы это сделать:

var num = 10, 
    reverse = false; 

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

Я хотел бы проверить обратный только один раз вне цикла.

+1

Что вы на самом деле пытаетесь сделать? Поскольку, если он создает массив или цикл в массиве, всегда существует функция javascript reverse http://www.w3schools.com/jsref/jsref_reverse.asp, который вы можете назвать – CaffGeek

+1

w3schools, не так хорош. Проверьте [w3fools] (http://w3fools.com/). – DwB

ответ

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:

Как отмечалось в комментариях ниже, если i не объявлена ​​в другом месте и вы не собираетесь для того, чтобы быть глобальным, а затем объявить его с другими переменными, объявлен.

И если вы не хотите изменять значение num, тогда назначьте его 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

Ницца. Я собирался предложить 'for (i = num; i--;) log (i);', но [консенсус] (http://stackoverflow.com/questions/1340589/javascript-are-loops-really- быстрее в обратном порядке), кажется, что ваш метод является самым быстрым. – palswim

+0

К операциям: имейте в виду, что 'num' будет изменен при печати в обратном порядке, поэтому обязательно сделайте копию исходного значения, если вы планируете использовать это значение в будущем. –

+0

@ Daniel - Очень верно. Если это вызывает беспокойство, быстро замените оператор '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

Здесь 'i <= end' выдаст проблемы, так как проверка должна быть' i> = 0' в обратном порядке. –

+2

должен быть i! = End – Equiso

+0

Эй, это правильно. Исправлено: – Jerome

7

Использование Try 2 петли:

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

Я собирался опубликовать почти то же самое, что и это. Это кажется мне наиболее естественным и читаемым решением, а также эффективным, обратный флаг проверяется только один раз, а не каждый раз через цикл. – Jay

0

А в чем проблема с:

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

}

+1

Возможно, в производственном коде будет больше проходить внутри цикла, чем простой 'console.log'? – meagar

+0

@meagar: Если это так, нажмите все внутри цикла в функцию. – 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); 
} 

Это equival лор к следующему, который является более удобным для чтения, но менее компактный:

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

Редактировать:
На самом деле, эти два решения не являются идентичными, потому что первым имеет дополнительную операцию приращения. Тем не менее, он пренебрежимо мал с точки зрения производительности. Если вы действительно хотите получить компактное решение, которое имеет лучшую производительность, вы можете сделать следующее (не для слабонервных):

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

Это имеет преимущество, имеющий единую структуру управления, один тест в каждом цикле и добавление одного итератора. Это не так быстро, как приращение/декремент итератора, но только незначительно.

+0

lol. Вы пишете свое, когда я писал (страница обновилась, когда были опубликованы новые ответы). : P Я злоупотребляю тернарными заявлениями. Рад видеть того, кто пишет, как я. – XstreamINsanity

+0

Нет злоупотреблений там, где есть трояны ... Я считаю, что это злоупотребление, только если вы не используете возвращаемое значение тройного выражения, например условие? doSomething(): doSomethingElse(); --- Полностью вне точки, хотя ... –

+0

Мне нравится ваше решение, но я обнаружил, что Патрик еще более ясен. – Raspo

1

Я думаю, что это соответствует вашим требованиям:

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

Рой похож на мой, но вот что я думаю. Я дам вам то, что я написал на C#, и как я думаю, что это переводится в 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); 
    } 

А вот еще один способ
Javascript

var num = 10, 
     reverse = false; 

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

    } 
+1

Все они все еще проверяют обратный флаг на каждой итерации цикла. – Jay

+0

lol. Мой плохой, я не видел этой части в вопросе. Спасибо, что дали мне знать. Однако, к OP, если вы беспокоитесь о производительности, я бы этого не сделал. Я подумаю о чем-то другом, если смогу. – XstreamINsanity

+0

Я думаю, что ОП не знал о тройных высказываниях, думая, что им придется иметь if if else в их цикле. Тем не менее, я все еще думаю о другом. – XstreamINsanity

0

Это похоже на работу:

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

Конечно, в таком языке, как Javascript должен быть способ определить локальную функцию и использовать это в цикле?

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

Не зная Javascript, хотя, я не знаю, какую фактическую форму будут выполнять определения функций.

1

Вот как я всегда делал обратные петли:

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

Вы должны прочитать вопрос, прежде чем отвечать;) – yckart

2

Я просто наткнулся на необходимость этого на другой день. Здесь нет, как я это сделал:

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

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

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

Нет необходимости в отдельных петлях, и нет необходимости делать математику, чтобы вычислить правильный i в петле.

Так что если reverse является true ...

  • i (который представляет наш первый пункт) становится num - 1, поэтому мы теперь, начиная с того, что был бы последний пункт

  • num (который представляет собой запредельное значение) становится -1, поэтому мы теперь останавливаемся на том, что было бы первым предметом

  • direction является -1, что означает, что он будет уменьшать, когда мы делаем i += direction

Так, меняя нашу отправную точку с нашей конечной точкой и изменяя изменение i от 1 до -1, мы будем идти вверх или вниз на основе этих изменений.

Смежные вопросы