James Becker James Becker - 4 months ago 7
Javascript Question

Why is this call to a simple helper function causing an infinite loop?

I've been debugging this for hours to no avail.

The following code checks whether each number in a series of numbers has no repeating digits (

111
should return
false
;
123
should return
true
) and return an array of all numbers in the series which contain no repeating digits.

The array should be populating with values which the helper function returns as
true
for each value in the array, but running
noRepeats()
causes an infinite loop or a long array of 1s. What is causing this?



// DO NOT RUN AS IS; POTENTIAL INFINITE LOOP

var noRepeatDigits = function (n) {
n = n.toString();
for ( i = 0 ; i < n.length ; i ++ ) {
for ( j = i + 1 ; j < n.length ; j ++ ) {
if ( n.charAt(i) === n.charAt(j) ) {
return false;
}
}
}
return true;
};

console.log( noRepeatDigits(113) ); // false
console.log( noRepeatDigits(123) ); // true

var noRepeats = function (n1, n2) {
var arr = [];
for ( i = n1 ; i <= n2 ; i ++ ) {
if ( noRepeatDigits(i) ) {
arr.push(i);
}
}
return arr;
};

console.log( noRepeats(1, 100) );




Answer

You forgot to var i, so the iterator is global and the two functions using it overwrite each other. This causes unexpected behaviour at best, an infinite loop at worst.

However you can simplify your noRepeatDigits function a lot:

noRepeatDigits = function(n) {
    return !n.toString().match(/(.).*?\1/);
};

This effectively does what your original function did, but offloads the heavy work to built-in, lower-level functions which generally speaking are significantly faster.