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) intoarrayOfWords
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!