Why .split(/\s+/) doesn't erase the white space at the beginning of the string?

Continuing the discussion from freeCodeCamp Challenge Guide: Apply Functional Programming to Convert Strings to URL Slugs:

Here’s the code I came up with:

var globalTitle = "Winter Is Coming";

// Add your code below this line
function urlSlug(title) {
  return title
    .toLowerCase()
    .split(/\s+/)
    .join("-");
}
var winterComing = urlSlug(globalTitle); 

And it didn’t pass when the string is " Winter is coming" and the solution needs a .trim() method. I don’t understand why .split(/\s+/) doesn’t erase all white space?

1 Like

It doesn’t erase, it splits on the given seperator.

" Winter is coming"

split gives you

["", "Winter", "is", "coming"]

So the whitespace at the start, it’s split on that as well, but split implies there is something to split to: there has to be two things that come out the other end. The only thing before the seperator is an empty string, so the split at the start is from " Winter" to “” and “Winter”. Joining that puts the given joining character between each element in that array:

"-Winter-is-coming"
2 Likes

Thanks so much. I was like a bug in my head. So .split() needs a thing to start splitting, right? If there’s space at the beginning, it’s count that space as the first thing to start?

“split” is splitting the string “around” the given pattern.
So if you tell it to split around whitespaces, it will create a list of everything that is in front and behind of whitespaces - INCLUDING empty strings.
” would literally be split into three empty strings ["", "", ""]

As to why '', it may be more remembering than understanding though.

The same when there is no splitting "hello".split('@') will return 'hello'

This is why MDN explicitly tells what happens in these cases:

If separator is omitted or does not occur in str, 
the returned array contains one element consisting of the entire string.

If separator appears at the beginning (or end) of the string, it still has the 
effect of splitting. The result is an empty (i.e. zero length) string, 
which appears at the first (or last) position of the returned array.

If separator is an empty string (""), str is converted 
to an array of each of its UTF-16 "characters". 

This is just some ideas I came to while playing with it.

We can define split as:

split will grab what is before and after the split character:

"before@after".split('@')
['before', 'after']

Remove before

"@after".split('@')
[' ', 'after']

Remove both

'@'.split('@')
['', '']

The idea is that:

  • split will return what is before and after the splitting character,
  • when there is nothing, this is written "".
Optional stuff

What do you think about?

"".split("")
// or 
"abc".split("")

That would be infinite imho. So one of the rules of split is:

  • If separator is an empty string ( "" ), str is converted to an array of each of its UTF-16 “characters”.

So the second nicely returns "a","b","c".

Dev Docs, MDN

2 Likes

PD I spent a good while thinking what would happen in this cases, and it may be a good exercise:

"".split("")
"hello".split("@")
"abc".split("")
" abc ".split(/\s/)

I’m grateful. So much detail.

1 Like

You’re welcome, and thank you for the question too.