- Move the recursion,
return
the recursion, and
- Add an essential condition to end recursion:
const LETTERS = [/AB/g, /BA/g, /CD/g, /DC/g];
const stringGame = (string) => {
let newString = '';
if (string.length <= 1) return string;
LETTERS.forEach(regExToCheck => {
if (string.match(regExToCheck)) {
newString = string.replace(regExToCheck, '')
}
})
// Moved, returned, and ended recursion
return ('' === newString) ? string : stringGame(newString);
}
// Expect answer: CAACC
console.log(stringGame('ABDCABCABAAABCCCD'))
When recursing the function, i.e., when executing the function within itself, the return
'ed value of that execution needs to be used, typically return
'ed:
return stringGame(newString);
...in order for it to bubble back up the levels of recursion.
Also, since the replace()
function is using a regex global replacement flag (g
) all, for example, AB
's, are being replaced in a single execution, so there's no need to recurse within the forEach()
loop:
LETTERS.forEach(regExToCheck => {
if(string.match(regExToCheck)) {
newString = string.replace(regExToCheck, '')
}
stringGame(newString); // <-- double oops
})
Rather, recurse after the loop, AND return
the value of the execution:
LETTERS.forEach(regExToCheck => {
if(string.match(regExToCheck)) {
newString = string.replace(regExToCheck, '')
}
})
return stringGame(newString);
One more principle of recursive functions is providing exit strategies—define what conditions to end the recursion, bubble back up, and return a final result.
The only exit condition provided is:
if (string.length <= 1) return string;
Surely if there's only one character left no match will be found—a proper time to end recursion. However, and more importantly, there also needs to be a path to exit when there are more than one characters but no matches can be found.
There are multiple ways to determine this but in the case provided in the question the most expedient is when after looping through the regex/replace routine no changes were made to the string. Since with every recursion the stringGame()
function instantiates an empty string (newString
) if, after looping through the regex/replace routine, newString
is still an empty string, this indicates there were no matches found and it's time to end recursion:
if ( '' === newString ) {
return string;
}
else {
return stringGame(newString);
}
...otherwise, recurse.