I am trying to e up with an algorithm for an "approaching" behavior between two integers. Basically, given two integers, a
and b
, i want a
to "approach" b
, even if b
is less than a
. The way i think this should look is a swapping of the loop incrementer function:
for (var i = a; approachCond(i, a, b); approachDir(i,a, b)) {
// some fn(a, b);
}
where
approachCond(i, a, b) {
return a < b ? i < b : i > b;
}
and
approachDir(i, a, b) {
return a < b ? i++ : i--
}
However, when i try doing this the browser freezes (Chrome). Does anyone know how to dynamically alter the direction of a loop?
I am trying to e up with an algorithm for an "approaching" behavior between two integers. Basically, given two integers, a
and b
, i want a
to "approach" b
, even if b
is less than a
. The way i think this should look is a swapping of the loop incrementer function:
for (var i = a; approachCond(i, a, b); approachDir(i,a, b)) {
// some fn(a, b);
}
where
approachCond(i, a, b) {
return a < b ? i < b : i > b;
}
and
approachDir(i, a, b) {
return a < b ? i++ : i--
}
However, when i try doing this the browser freezes (Chrome). Does anyone know how to dynamically alter the direction of a loop?
Share Improve this question edited Jul 29, 2015 at 20:13 dopatraman asked Jul 29, 2015 at 20:11 dopatramandopatraman 13.9k29 gold badges97 silver badges163 bronze badges 2- have an if else with a different for loop in each one – depperm Commented Jul 29, 2015 at 20:17
- Thats what im doing now, but i want to avoid that if a more elegant solution is possible. – dopatraman Commented Jul 29, 2015 at 20:18
6 Answers
Reset to default 3I think it's a little clearer to read if you just use a while
loop:
'use strict';
let a = 12, b = 6;
let i = a;
while (i !== b) {
console.log(i);
i += a < b ? 1 : -1;
}
I even left the cute ternary since people seem so opposed to if-statements these days.
Your browser freezes because you're not altering the correct i
. You're only manipulating the i
that is in the approachDir
function. If you return it & set the for
scope i
to the new value, it will work.
Try:
for (var i = a; approachCond(i, a, b); i = approachDir(i,a, b)) {
// some fn(a, b);
}
approachDir(i, a, b) {
return a < b ? i + 1 : i - 1
}
It seems as though you are overplicating something that is not that hard. You can just set the step to positive or negative. e.g.
var a = 20;
var b = 5;
for (var step = a > b ? -1 : +1; a != b; a += step)
{
console.log(a);
}
The problem is in approachDir
. i++
and i--
are post-increment and post-decrement. That means they update the variable after they return its original value. So the function is returning the original value, not the updated one. To update the variable before returning, you should use ++i
or --i
.
But you don't need to use an increment operator at all, since the local variable is going away immediately. Just return the new value.
function approachDir(i, a, b) {
return a < b ? i + 1 : i - 1;
}
You also need to reassign the variable in the loop:
for (var i = a; approachCond(i, a, b); i = approachDir(i, a, b)) {
...
}
The way you wrote your code, you assumed that variables are passed by reference, not by value, so that the increment in the function would modify the caller's variable.
One option is to change approachDir
to return a positive or negative value based on if a>b
. The middle statement can include an || and work either way.
function approachDir(a, b){
return a>b?-1:1;
}
var a=3;
var b=1;
for (var i = a; i<b||i>b; i+=approachDir(a, b)) {
console.log(i);
}
a=1;
b=3;
for (var i = a; i<b||i>b; i+=approachDir(a, b)) {
console.log(i);
}
I made a slight change to @mathletics answer:
function loopDynamic(from, to) {
const direction = from < to ? 1 : -1;
let i = from
while (i!== to) {
// do whatever with i
i += direction;
}
}