Viren Bhagat

Solving "Spinal Tap Case" / freeCodeCamp Algorithm Challenges

7/13/2020

'Spinal Tap Case'

Let's solve freeCodeCamp's intermediate algorithm scripting challenge, 'Spinal Tap Case'.

Starter Code

function spinalCase(str) {
  return str;
}

spinalCase('This Is Spinal Tap');

Instructions

Convert a string to spinal case. Spinal case is all-lowercase-words-joined-by-dashes.

Test Cases

spinalCase("This Is Spinal Tap") should return "this-is-spinal-tap".
spinalCase("thisIsSpinalTap") should return "this-is-spinal-tap".
spinalCase("The_Andy_Griffith_Show") should return "the-andy-griffith-show".
spinalCase("Teletubbies say Eh-oh") should return "teletubbies-say-eh-oh".
spinalCase("AllThe-small Things") should return "all-the-small-things".

Our Approach

The instructions for this challenge are short and to the point.

  • Our one input is str, a string. Looking at the test cases, there can be spaces or no spaces.
  • We must return a string.
  • We need to convert str to all lowercase and have each word separated by a '-' (I hear RegEx calling...).

I'm sure there could be non RegEx solutions, I did try one intially but it wouldn't work as it was only working if the words in str were separated by white spaces.

# Failed Attempt No. 1
"This Is Spinal Tap".split(' ').join('-').toLowerCase();
"this-is-spinal-tap"
// This worked

"The_Andy_Griffith_Show".split(' ').join('-').toLowerCase()
"the_andy_griffith_show"
// Nope

I figured RegEx would be the optimal solution for this challenge. I am not that familiar or comfortable with using it but let's give it a try.

The cases we had to consider were: white spaces, underscores, and uppercased letters.

There are a lot of resources and tools for learning about Regular Expressions if you'd like to read more:

Regular Expressions (MDN)

https://regexr.com/

Regular expressions on javascript.info

In this challenge, I plan to use the .replace() method. It looks for the pattern we provide and will replace it with what we use in the second argument. More can be read about how to use it on MDN: String.replace()

Here is a small example of how to use it:

// String.replace(RegEx here, replacement)
console.log('Hello World'.replace(/[A-Z]/, '$'))
'$ello World'
// The above replaces the first capital letter it finds with a '$'

// Adding the /g modifier will go through every capital letter, not just stop after the first capital letter found
console.log('Hello World'.replace(/[A-Z]/g, '$'))
'$ello $orld'

So now, knowing the above (kind of), and looking at the test cases, we should try to create a whitespace in the cases were there isn't one:

spinalCase("thisIsSpinalTap")
spinalCase("AllThe-small Things")

We want to create a space between lower case and upper case words. We want a RegEx that will replace 'thisIs' to 'this Is'.

([a-z]) is for all lower cased letters and ([A-Z]) is for upper cased letters so we can begin with that.

After a lot of reading, I found this to be helpful on how to set up this replace() function.

MDN: RegExp.$1-$9

console.log('helloWorld'.replace(/([a-z])([A-Z])/g, '$1 $2'));
// "hello World"

The above adds a space between a lower case letter and an upper case letter.

console.log("thisIsSpinalTap".replace(/([a-z])([A-Z])/g, '$1 $2'));
// "this Is Spinal Tap"

So now we just have to figure out how to replace white spaces (or underscores) with dashes and then lower case the whole string.

From reading some documentation, \s is what we want to use for white spaces. For underscores, we can use _. The OR operator is |.

The other thing to add is +. From MDN, "Matches the preceding item "x" 1 or more times. Equivalent to {1,}. For example, /a+/ matches the "a" in "candy" and all the "a"'s in "caaaaaaandy"."

So our function should now look something like this,

replace(/([a-z])([A-Z])/g, '$1 $2').replace(/\s+|_+/g, '-')

To test it out (with the hardest test case),

"AllThe-small Things".replace(/([a-z])([A-Z])/g, '$1 $2').replace(/\s+|_+/g, '-')
// "All-The-small-Things"

All that is left now is to lower case all the letters. We can use a built-in string method, no need for RegEx.

String.toLowerCase() on MDN

As always, make sure your function returns something.

Our Solution

function spinalCase(str) {
  return str.replace(/([a-z])([A-Z])/g, '$1 $2').replace(/\s+|_+/g, '-').toLowerCase();
}

spinalCase('This Is Spinal Tap');

Links & Resources

'Spinal Tap Case' Challenge on fCC

freeCodeCamp

Donate to FCC!

Solution on my GitHub

Thank you for reading!

fcc, javascript, algorithms