I'll start of with a simplified example of my problem.
function foo(arr) {
let limit = 1,
count = 0;
for (let i=0, len=arr.length; i<len;) {
if (arr[i] === '0' || arr[i] === '1') {
let start = i;
do {
if (i - start >= limit) {
count++;
}
i++;
} while (i < len && arr[i] === '0' || arr[i] === '1');
} else {
i++;
}
}
return count;
}
function bar(arr) {
let limit = 1,
count = 0;
for (let i=0, len=arr.length; i<len;) {
if (arr[i] === '0' || arr[i].charCodeAt(0) === 49) {
let start = i;
do {
if (i - start >= limit) {
count++;
}
i++;
} while (i < len && arr[i] === '0' || arr[i].charCodeAt(0) === 49);
} else {
i++;
}
}
return count;
}
let arr = ['0', '2', '3', '0', '1', '0', '4', '2', '0'];
console.log(bar(arr));
console.log(foo(arr));
The above functions return the total count of occurrences of a pattern in an array, starting the count after a certain consecutive limit. They are simplified examples of my actual function, where I want to evaluate an expression like arr[i].charCodeAt(0) === 49
only if i < len
.
The foo function works as expected, but if I include a function call inside my while condition like in bar, it is evaluated first, and it throws a TypeError trying to evaluate an undefined index.
I could move that expression inside the do-while-loop before another i<len
check. I would like to know why functions are prioritized above "left-to-right" evaluation, and if there is something else I can do to prevent it.
it throws a TypeError trying to evaluate an undefined index.
because arr[9]
doesn't exists, just put a console statement to check the same.
Demo
function foo(arr) {
let limit = 1,
count = 0;
for (let i=0, len=arr.length; i<len;) {
if (arr[i] === '0' || arr[i] === '1') {
let start = i;
do {
if (i - start >= limit) {
count++;
}
i++;
} while (i < len && arr[i] === '0' || arr[i] === '1');
} else {
i++;
}
}
return count;
}
function bar(arr) {
let limit = 1,
count = 0;
for (let i=0, len=arr.length; i<len;) {
if (arr[i] === '0' || arr[i].charCodeAt(0) === 49) {
let start = i;
do {
if (i - start >= limit) {
count++;
}
i++;
console.log(i);
} while (i < len && arr[i] === '0' || arr[i].charCodeAt(0) === 49);
} else {
i++;
}
}
return count;
}
let arr = ['0', '2', '3', '0', '1', '0', '4', '2', '0'];
console.log(bar(arr));
console.log(foo(arr));
Explanation
Your statement is equivalent of writing
var a = 1;
var b = 2;
a < 1 && b < 2 || true; //return true
a < 1 && b < 2 || false; //return false
because you have used || in the expression without ()
, it will get evaluated unless first two expressions are true
.
Use ()
as
} while (i < len && (arr[i] === '0' || arr[i].charCodeAt(0) === 49));
Demo
function foo(arr) {
let limit = 1,
count = 0;
for (let i=0, len=arr.length; i<len;) {
if (arr[i] === '0' || arr[i] === '1') {
let start = i;
do {
if (i - start >= limit) {
count++;
}
i++;
} while (i < len && arr[i] === '0' || arr[i] === '1');
} else {
i++;
}
}
return count;
}
function bar(arr) {
let limit = 1,
count = 0;
for (let i=0, len=arr.length; i<len;) {
if (arr[i] === '0' || arr[i].charCodeAt(0) === 49) {
let start = i;
do {
if (i - start >= limit) {
count++;
}
i++;
console.log(i);
} while (i < len && (arr[i] === '0' || arr[i].charCodeAt(0) === 49));
} else {
i++;
}
}
return count;
}
let arr = ['0', '2', '3', '0', '1', '0', '4', '2', '0'];
console.log(bar(arr));
console.log(foo(arr));