Consider a string whose first letter is always "M" and whose other characters can be pretty much any combinations of "I"s and "U"s (no other letter allowed, just Is and Us). For example: MIU, MUI, MIUIU, MUIIUIU, MUIIIUIIIUIII, MIUUIUIIIUUI are all strings of this kind.
I want a function that given any such string as input, returns an array with all the possible ways the pattern "III" can, if it appears at all in the input string, be replaced with "U" in the input. For example, there are 2 ways "III" can be replaced with "U" in "MIIII", namely MUI and MIU. Therefore, the function should, given MIIII as input, return [MUI, MIU].
This is my (flawed) function. The idea behind it is that of looping through the input string (i.e. MIstring) looking for "III". Each time "III" is found, MIstring is added to the IIIoptions array but with "U" replacing "III".
function ruleThree() {
var IIIoptions = [];
for (var i = 0; i < MIstring.length; i++) {
if (MIstring.slice(i, i+3) === "III") {
IIIoptions.push(MIstring.replace(MIstring.slice(i, i+3), "U"));
}
}
return IIIoptions;
}
Given the input MIIII, I expected the function to return [MUI, MIU]. However, it returns [MUI, MUI]. I have tried with different inputs and it displays the same problem, that is, all the items in the array are the same. For example, given the string MIIIIUIIIIU it gives me [MUIUIIIIU, MUIUIIIIU, MUIUIIIIU, MUIUIIIIU] instead of [MUIUIIIIU, MIUUIIIIU, MIIIIUUIU, MIIIIUIUU]. So the function gets the number of "III"s contained in MIstring right, but it does not return the array that I would expect it to return.
What is wrong with my function?
.replacealways replaces the firstIII-- no matter what the actual position is. What you need isresult.push(slice-before-the-position + U + slice-after-the-position)instead ofreplace.for()loop, usereduce()and avoid the side-effect nature of your code.