As Joseph's answer illustrates a regular expression could be used to eliminate the for
loop, though it would need to be escaped and surrounded by word boundary meta characters1.
The current code has a for
loop which iterates from zero to one less than the length of the input string str
. In the example code
console.log(myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped"));
That string has 42 characters so the for
loop iterates from zero to 41. The first if
checks before === newStr[a]
. In that example string, newStr
is an array with nine elements so after a
has a value of 10 or more it is comparing before
with undefined
, which will never evaluate to true
.
The second conditional block, which starts with:
if (before[0] === before[0].toUpperCase()) {
is evaluated on every iteration of the loop, so if before
starts with an uppercase character, it that conditional will always evaluate to true
. This leads to str.replace()
being called on every iteration of the loop regardless of whether the previous block was executed. That whole block could be moved before the for
loop and used to assign a value to the string used in the call to str.replace()
later in the loop.
The code also uses let
for newStr
and var
for swap
. Both variables are never re-assigned so const
can be used. This helps avoid accidental re-assignment if and when code is expanded.
The for
loop could be replaced with a for...of
Loop which would simplify the syntax- especially eliminating the need to increment the counter variable a
for dereferencing the string characters.
The name newStr
would be better called words
since it is an array of word.
Putting the advice above together gives code like this:
function myReplace(str, before, after) {
const words = str.split(' ');
let newSubstr = after;
if (before[0] === before[0].toUpperCase()) {
newSubstr = after[0].toUpperCase() + after.slice(1);
}
for (word of words) {
if (word === before) {
str = str.replace(before, newSubstr);
}
}
return str;
}
console.time && console.time('replace');
const replacedStr = myReplace("A quick brown fox Jumped over the lazy dog", "Jumped", "leaped");
console.timeEnd && console.timeEnd('replace');
console.log('replaced string: ', replacedStr);
Since the string gets split into an array, that array could be used to hold the sub-strings with replacements and then joined after the loop. This does seem slightly slower compared to the previous example.
function myReplace(str, before, after) {
const words = str.split(' ');
let newSubstr = after;
if (before[0] === before[0].toUpperCase()) {
newSubstr = after[0].toUpperCase() + after.slice(1);
}
for ([index, word] of words.entries()) {
if (word === before) {
words.splice(index, 1, newSubstr)
}
}
return words.join(' ');
}
console.time && console.time('replace');
const replacedStr = myReplace("A quick brown fox Jumped over the lazy dog", "Jumped", "leaped");
console.timeEnd && console.timeEnd('replace');
console.log('replaced string: ', replacedStr);