4

Мне нужно пройти через число (xx). xx всегда начинается с нуля. Моя проблема в том, что если переменная moveDirection равна +1, то xx увеличивается до достижения положительного значения range. Если moveDirection равно -1, то xx уменьшается до достижения отрицательного значения range.Как уменьшить дублирование кода в этом примере

В приведенном ниже коде я сделал это с помощью проверки оператора if для moveDirection, затем я продублировал цикл for и отредактировал значения для каждого случая. Мой код находится в ActionScript3, но язык не имеет значения.

var p:Point; 
var xx:int; 

if (moveDirection > 0) 
{ 
    for (xx = 0; xx < range; xx++) 
    { 
     if (hitTestPoint(xx, yy)) 
     { 
      return true; 
     } 
    } 
} 
else 
{ 
    for (xx = 0; xx > range; xx--) 
    { 
     if (hitTestPoint(xx, yy)) 
     { 
      return true; 
     } 
    } 
} 

Есть ли лучший способ сделать это, возможно, без дублирования цикла for? Если есть какой-либо другой совет, он был бы весьма признателен.

ответ

10
for (xx = 0; xx != range; xx += moveDirection) 
{ 
    if (hitTestPoint(xx, yy)) 
    { 
     return true; 
    } 
} 

Это предполагает, что moveDirection будет либо 1, либо -1 для перехода вверх или вниз, соответственно. Кроме того, вам придется слегка изменить свой диапазон для правильной работы! =. Но он сокращает код.

+0

Я бы изменил имя 'moveDirection' на' motionVector' или что-то в этом роде, чтобы понять, что он хранит. 'moveDirection' звучит слишком сильно, как переименование или что-то еще :) – porges

+0

True. Я просто ленился и использовал предопределенные переменные, поэтому мне не пришлось самостоятельно определять их. : P –

+0

Очень элегантный! Огромное спасибо. Меня всегда поражают всевозможные способы использования циклов (или любых других циклов). –

0

Вот пример в Java (see also on ideone.com):

static void go(final int range, final int direction) { 
    for (int i = 0; i != direction*range; i += direction) { 
     System.out.println(i); 
    }  
} 

Тогда вы можете сделать:

 go(5, +1); // 0, 1, 2, 3, 4 
     go(5, -1); // 0, -1, -2, -3, -4 

Если вы хотите разместить необратим шаг, то проще определить третий параметр, как следующим образом:

static void go(final int range, final int step, final int direction) { 
    for (int i = 0; i < range; i += step) { 
     System.out.println(i * direction); 
    }  
} 

Тогда вы можете сделать:

 go(10, 3, +1); // 0, 3, 6, 9 
     go(10, 3, -1); // 0, -3, -6, -9 
+0

Это не так; условие во втором предложении цикла for также отличается. И направление может иметь величину больше 1. – Borealid

1

Судя по коду, это действительно не имеет значения, в каком направлении петля работает - вы просто возвращаются true если таковые hitTestPoint возвращается true для некоторого значения в диапазоне. Если это так, то другая возможность будет что-то вроде:

var start:int = min(0, range); 
var stop:int = max(0, range); 

for (xx = start; xx!=stop; xx++) 
    if (hitTestPoint(xx,yy) 
     return true; 
+1

Если существует несколько значений xx, для которых hitTestPoint (xx, yy) истинно, или особенно, если hitTestPoint имеет побочные эффекты, это, безусловно, может изменить поведение. –

1

Другая возможность:

int i; 
for (i = abs(range), xx = 0; --i >= 0; xx += moveDirection){ 
    if (hitTestPoint(xx, yy) return true; 
} 
+0

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

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