Как изменить порядок в цикле FOR
У меня есть простой оператор FOR:
var num = 10,
reverse = false;
for(i=0;i<num;i++){
console.log(i);
}
когда reverse является ложным Я хочу, чтобы он возвращал что-то вроде [0,1,2,3,4,5,6,7,8,9]
но если reverse истинно, он должен возвратить [9,8,7,6,5,4,3,2,1,0]
Каков наиболее эффективный способ получить этот результат, не проверяя каждый раз, если reverse является истинным или ложным внутри цикла?
Я не хочу этого делать:
var num = 10,
reverse = false;
for(i=0;i<num;i++){
if(reverse) console.log(num-i)
else console.log(i)
}
Я хотел бы проверить reverse только один раз за пределами цикла.
Ответы
Ответ 1
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 ); }
Ответ 2
Попробуйте использовать 2 цикла:
if (reverse) {
for(i=num-1;i>=0;i--){
console.log(i)
}
}
else {
for(i=0;i<num;i++){
console.log(i)
}
}
Ответ 3
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);
}
Это эквивалентно следующему, более читабельному, но менее компактному:
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:
На самом деле эти два решения не идентичны, потому что первый имеет дополнительную операцию приращения. Тем не менее, он пренебрежимо мал с точки зрения производительности. Если вы действительно хотите получить компактное решение с лучшей производительностью, вы можете сделать следующее (не для слабонервных):
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);
}
Это имеет то преимущество, что имеет единую структуру управления, один тест в каждом цикле и одно дополнение итератора. Это не так быстро, как увеличение/уменьшение итератора, но только незначительно.
Ответ 4
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
Я только наткнулся на необходимость этого на днях. Вот как я это сделал:
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
, мы будем идти вверх или вниз на основе этих изменений.
Ответ 6
Я думаю, это соответствует вашим требованиям:
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));
}
Ответ 7
Вот как я всегда делал обратные циклы:
for (i = num; --i >= 0; ) ...
Ответ 8
И какая у вас проблема с:
if (reverse)
{
for(i=num-1; i>=0;i--){
console.log(i);
}
}
else
{
for(i=0;i<num;i++){
console.log(i)
}
}
}
Ответ 9
Рой похож на мою, но вот что я думал. Я дам вам то, что я написал на С#, и как я думаю, что это переводится в Javascript.
С#
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));
}
Ответ 10
Кажется, что работает:
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);
}
Ответ 11
Разумеется, на языке, таком как 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, хотя я не знаю, какую фактическую форму будут выполнять определения функций.