Reputation: 93
I have this function :
function simplifyString (string)
{
var charsToFind = new Array(/[áàâãä]/g, /[éèêë]/g, /[íìîï]/g, /[óòôõö]/g, /[úùûü]/g, /ç/g, /[- \'&_]/g),
charsToReplace = new Array('a', 'e', 'i', 'o', 'u', 'c', '');
string = string.toLowerCase();
for (i = 0; i < charsToFind.length; i++)
{
string = string.replace(charsToFind[i], charsToReplace[i]);
}
return string;
}
And I use it inside a loop, like this :
for (i = 0; i < objects.length; i++)
{
var value = simplifyString(objects[i].innerText);
console.log(value);
console.log(i);
}
Objects variable contains an array of elements.
Console will only show me the inner text of the first element, and i
will display the length of my array - 1.
If I remove the loop of my function, console will show me inner text of every object and the correct serie of numbers.
I don't quite understand this behaviour, any help?
Upvotes: 0
Views: 47
Reputation: 1592
for (i = 0; i < objects.length; i++)
for (i = 0; i < charsToFind.length; i++)
TO...
for (var i = 0; i < objects.length; i++)
for (var i = 0; i < charsToFind.length; i++)
OR...
for (let i = 0; i < objects.length; i++)
for (let i = 0; i < charsToFind.length; i++)
Note on browser support: In IE 11 "let variables are not bound separately to each iteration of for loops" Caniuse - let.
You are currently declaring i
, in both for
loops, without an identifier var, let, const
so it is being assigned to the same i
property on the global object rather than declaring an new locally scoped variable. The for
loop inside simplifyString (string)
is assigning a new value to the same i
as the first for
loop and screwing everything up.
* As mentioned in comments, this how you could use reduce()
to make your code more readable, minimize unnecessary side-effects/mutations and couple your tests
directly with their replacement values
to avoid some confusion...
var charReplacements = [
{ test: /[áàâãä]/g, value: 'a' },
{ test: /[éèêë]/g, value: 'e' },
{ test: /[íìîï]/g, value: 'i' },
{ test: /[óòôõö]/g, value: 'o' },
{ test: /[úùûü]/g, value: 'u' },
{ test: /ç/g, value: 'c' },
{ test: /[- \'&_]/g, value: '' }
];
function simplifyString (string) {
return charReplacements
.reduce((str, {test, value}) =>
str.replace(test, value)
, string);
}
NOTE: If you're running this over large datasets I'd ask someone smarter than me how do this with a few lines of regex, which would be much more efficient than iterating over the replacers
Upvotes: 1
Reputation: 160
The issue is with how your loop counters are scoped. Instead of doing
for (i = 0; ...)
You should declare your loop counter as
for (let i = 0;...)
So that it is scoped to your loop block.
If you declare your loop variable as just 'i=0', then 'i' has a global scope. In this scenario, the 'i' you are using in your simplifyString loop is the same 'i' that you are using in the loop that calls simplifyString! Since simplifyString increments 'i' after you call it the first time, the invoking loop terminates prematurely.
Upvotes: 1