Code Challenge #2: Reversing Words with 5 or More Characters in a String

Code Challenge #2: Reversing Words with 5 or More Characters in a String

Welcome back to my Code Challenge series!

Today's challenge is from the Web Developer Bootcamp Discord group, passed on from Codewars. I hope you enjoy it as much as I did!

The Challenge

Write a function that takes in a string of one or more words and returns the same string, but with words of 5 or more letters reversed.

  • Strings passed in will consist of only letters and spaces
  • Spaces will be included only when more than one word is present
spinWords("Hey fellow warriors") // "Hey wollef sroirraw" 
spinWords("This is a test") // "This is a test" 
spinWords("This is another test") // "This is rehtona test"

STOP READING if you want to try this on your own!

My Solution

It was interesting to see how other people did this on Codewars! Mine isn't the most optimized option, but it's what I came up with.

// Input validation
const isAllLettersAndSpaces = string => {
  const arrayOfCharacters = string.split("");

  return arrayOfCharacters.every(character => /[a-z]|\s/i.test(character));
}

// Function to reverse words with >=5 letters in string
const spinWords = string => {
  if (!isAllLettersAndSpaces(string)) {
    return null;
  }

  const arrayOfWords = string.trim().split(" ");

  arrayOfWords.forEach((word, index, array) => {
    if (word.length >= 5) {
      const reversedWord = word.split("").reverse().join("");
      array.splice(index,1,reversedWord);
    }
  })

  return arrayOfWords.join(" ");
}

// Test
const newString = spinWords('I love eating icecream because it makes me happy');
console.log(newString); // "I love gnitae maerceci esuaceb it sekam me yppah"

Walkthrough

I included input validation thinking we had to, so I'll leave it in the code for practice. Real projects include validation, so why not?

Input Validation

const isAllLettersAndSpaces = string => {
  const arrayOfCharacters = string.split("");
  // Splits all characters of string into substrings in an array

  return arrayOfCharacters.every(character => /[a-z]|\s/i.test(character));
  // returns true if every character is between a-z or is a space, else false
}

The function isAllLettersAndSpaces is a validator that returns a boolean of whether or not the string includes all letters and/or spaces.

const arrayOfCharacters = string.split("");
// Splits all characters of string into substrings in an array

The first line uses the split method to separate each character into an array, arrayOfCharacters.

return arrayOfCharacters.every(character => /[a-z]|\s/i.test(character));
// returns true if every character is between a-z or is a space, else false

The last line uses the every method to check if every character in arrayOfCharacters passes the regular expression, /[a-z]|\s/i. It returns true if every character returns true, otherwise it returns false.

I'm still getting the hang of regular expressions, but [a-z] is characters between a-z, | is OR, \s is for spaces, and i is for a case-insensitive search.

The test method returns true if it returns a match for the regular expression, otherwise false.

spinWords Function

// Function to reverse words with >=5 letters in string
const spinWords = string => {
  if (!isAllLettersAndSpaces(string)) {
    return null;
  }

  const arrayOfWords = string.trim().split(" ");


  arrayOfWords.forEach((word, index, array) => {
    if (word.length >= 5) {
      const reversedWord = word.split("").reverse().join("");
      array.splice(index,1,reversedWord);
    }
  })

  return arrayOfWords.join(" ");
}

Now, the fun begins!

Using isAllLettersAndSpaces

if (!isAllLettersAndSpaces(string)) {
    return null;
}

The first line returns null if isAllLettersAndSpaces returns false. Otherwise, this line gets skipped.

Trimming and Splitting the String

const arrayOfWords = string.trim().split(" ");

The next line uses:

  • Trim - to remove any whitespace at the start and end of the string.
  • Split - to put each word separated by a space (hence the " " parameter) into arrayOfWords as substrings

Within the forEach Method

arrayOfWords.forEach((word, index, array) => {
  if (word.length >= 5) {
    const reversedWord = word.split("").reverse().join("");
    array.splice(index,1,reversedWord);
  }
})

The next portion uses forEach on arrayOfWords to check if each word is at least 5 characters.

const reversedWord = word.split("").reverse().join("");

To reverse each word, I used 3 methods:

  • Split - to separate each character into an array
  • Reverse - to reverse the characters in the array
  • Join - to return a new string by concatenating the characters in the reversed array. The parameter "" is used so that there is no space within the word.
array.splice(index,1,reversedWord);

The next line uses splice so that at the index of the word-to-be-reversed, delete 1 word, and replace it with the reversedWord.

Returning the String

return arrayOfWords.join(" ");

arrayofWords is turned into a string by using join with the parameter " " to separate each word by a space.

It's Your Turn

Did you do this challenge differently? Let me know in the comments!

Feel free to play around with the CodePen!