The code consists of making an array from a range of numbers and as well having a third argument in which it indicates the steps from the numbers, if it has a step of 2 well for example it goes from [1,3,5] the code works fine except when I pass step
with a negative number as an argument e.g. NumberRange(10,5,-2)
; That's when the error appears, in the code it shows the logic I used for a negative step.
function NumberRange(start, end, step){
var numberList = [];
if(typeof(step) == 'undefined'){
if(start < end){
for(;start <= end; start ){
numberList.push(start);
}
console.log(numberList);
}
else if(start > end){
for(;start >= end;){
numberList.push(start);
start -= 1;
}
console.log(numberList);
}
}
else if(start > end && (Math.sign(step) == -1)){ // This is the logic I created when a negative step is given as an argument.
for(;start >= end; start - step){
numberList.push(start);
}
console.log(numberList);
}
else if(start < end && (Math.sign(step) == -1)){
console.log("Negative step cant work since the value of the beginning of the list is less than the end of it")
}
else{
for(;start <= end;){
numberList.push(start);
start = step;
}
console.log(numberList);
}
//return numberList;
};
NumberRange(10,5,-2);
CodePudding user response:
for(;condition;)
is just an ugly way of writing while(condition)
, don't do it.
Why it doesn't work is the for(;start >= end; start - step)
part, which doesn't update start
, just subtracts step
from it and throws the result away. Why it wouldn't work with -
is that step
is negative in that branch, so it should be start = step
in order to count downwards.
Generally you don't need the 4 branches, instead you could set step
to /-1 if it's undefined
, and if you really wanted to, you could still validate the sign of step
after setting it but before using it:
function NumberRange(start, end, step) {
if (typeof(step) == 'undefined') {
step = Math.sign(end - start);
}
if (Math.sign(step) != Math.sign(end - start)) {
console.log(`Can't count from ${start} to ${end} using ${step} as stepsize.`);
} else {
var numberList = [];
if (start > end) {
while (start > end) {
numberList.push(start);
start = step;
}
} else {
while (start < end) {
numberList.push(start);
start = step;
}
}
console.log(numberList.join());
return numberList;
}
}
NumberRange(10, 5, -2);
NumberRange(1, 2);
NumberRange(2, 1);
NumberRange(1, 3, 2);
NumberRange(1, 3, -2);
NumberRange(3, 1, -2);
NumberRange(3, 1, 2);
Then someone may get annoyed with having two loops with identical bodies, and after all, with a bit more complicated condition they can be collapsed into one:
function NumberRange(start, end, step) {
if (typeof(step) == 'undefined') {
step = Math.sign(end - start);
}
if (Math.sign(step) != Math.sign(end - start)) {
console.log(`Can't count from ${start} to ${end} using ${step} as stepsize.`);
} else {
var numberList = [];
while ((step > 0 && start < end) || (step < 0 && start > end)) {
numberList.push(start);
start = step;
}
console.log(numberList.join());
return numberList;
}
}
NumberRange(10, 5, -2);
NumberRange(1, 2);
NumberRange(2, 1);
NumberRange(1, 3, 2);
NumberRange(1, 3, -2);
NumberRange(3, 1, -2);
NumberRange(3, 1, 2);
CodePudding user response:
You have a typo in the third for
statement, the last part should be a subtraction assignment:
for(;start >= end; start = step){
numberList.push(start);
}
But the issue you are observing hints at an internal error in the V8 engine (a bug), probably an attempt to allocate a wrong amount of memory. I could reproduce it in Node.js and in Chrome with a simple endless loop like below.
var numberList = [];
while (true) {
numberList.push(1);
}
On my machine, this crashes after just a few seconds, when the array contains 112813858 elements.