0

I've been solving katas on codewars and I stumbled upon a general code problem that I can't seem to find an answer to.

This is my code:

function wave(str) {
   let arr = [];
   for (var i = 0; i < str.length; i++) {
       str[i].match(/\S/) && arr.push(str.replace(str[i], str[i].toUpperCase()));
   }
   return arr;
 };

(Note: Input is always lowercase.) In the case of wave("abc def"); the code does exactly what I want it to:

["Abc def", "aBc def", "abC def", "abc Def", "abc dEf", "abc deF"]

=> Function takes a string, capitalizes one letter of the string starting at str[0], pushes the new word to arr, increments i and repeats process until i < str.length, then returns arr with all the results.

However, if I input wave("acc def"); for example, only the first occurrence of the letter c will return capitalized:

["Acc def", "aCc def", "aCc def", "acc Def", "acc dEf", "acc deF"]

Question: Why does it 'jump' the second occurrence of 'c' and how can I target the second or nth occurrence of a character in a string?

3
  • "only the first occurrence" ~ Try global matching /\S/g ? Commented Aug 31, 2020 at 14:31
  • str.replace(str[i], ...) will only replace the first occurrence of the character at str[i] (hence it would also not work with cac def) Commented Aug 31, 2020 at 14:34
  • take the part left of str[i] (.slice()), take the uppercase version of str[i], take the part right of str[i] (.slice()) - combine them again Commented Aug 31, 2020 at 14:36

2 Answers 2

1

str.replace("x", "y") replaces the first occurrence of "x" in str with "y"
If there are only unique characters in the string your approach works, but it will fail when there are duplicated characters like in "acc def"

You could .slice() the string into three parts:

  • The part left of i -> .slice(0, i)
  • The character at index i -> str[i]
  • The remaining part after index i -> .slice(i + 1)

Modify str[i] as required and combine them back into a single string with .join("")

function wave(str) {
  const result = [];
  
  for (let i = 0; i < str.length; i++) {
    if (!str[i].match(/\S/)) continue;
    
    result.push([
                  str.slice(0, i),      /* the part left of str[i] */
                  str[i].toUpperCase(), /* str[i] */
                  str.slice(i + 1)      /* the remaining part right of str[i] */
                ].join(""))  // combine the parts in the array into a string
  }
  
  return result;
 };
 
 
 console.log(JSON.stringify(wave("abc def")));
 console.log(JSON.stringify(wave("acc def")));

Sign up to request clarification or add additional context in comments.

Comments

0

When you are saying str.replace(str[i], str[i].toUpperCase()), you are saying: "Replace the first occurrence of str[i] with str[i].toUpperCase()" and this is exactly what your program is doing.

Consider building your new string like this:

str.substring(0, i) + str[i].toUpperCase() + str.substring(i+1)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.