A slice() of substring(), please, with substr() on the side.

A slice() of substring(), please, with substr() on the side.

substr(), pal... we need to talk.

·

4 min read

Slice

Slice() will copy part of a string into a new one, without changing the original.

It takes two parameters:

  • an index of the first character to include in the new string, and
  • an optional index of where the excluded part starts

So this means slice(0, 3) will start at the [0] index and copy up to [3] but not including [3] in the new string.

If you don't provide a start index, or if you provide one that can't be converted to a number, then slice() will act as if you'd provided 0 as default, and then copy the string from 0 to the end.

See it in action:

let originalStr = 'Candy Mountain!'

originalStr.length
//output: 15

originalStr.slice()
//output: 'Candy Mountain!'

originalString.slice(999)
//output: ''

originalStr.slice('OMG')
//output: 'Candy Mountain!'

originalStr.slice(0,3)
//output: 'Can'

originalStr.slice('0','3')
//output: 'Can'

console.log(originalStr.slice(0,3), originalStr)
//output: Can Candy Mountain!

The second index being optional, if you don't provide a place for the new string to stop it'll just copy the original from the point the slice started.

Same thing will happen if you provide an end index that's undefined, or bigger than the string length.

let originalStr = 'Candy Mountain!'

originalStr.slice('3')
//output: 'dy Mountain!'

originalStr.slice(3)
//output: 'dy Mountain!'

originalStr.slice(0, 999)
//output: 'Candy Mountain!'

let a

originalString.slice(0, a)
//output: 'Candy Mountain!'

With slice() you can count backwards from the end of the string simply by using a negative integer. It'll start moving backwards from the end of the string, rather than forwards from the beginning.

Mind your integers though: if the end index represents a character that's before the start index then an empty string will be returned.

In other words, your end index has to be positioned "to the right" of your start index.

let originalStr = 'Candy Mountain!'

originalStr.length
//output: 15

originalStr.slice(0,-10)
//output: 'Candy'

originalStr.slice(4,-4)
//output: 'y Mount'

originalStr.slice(4,-10)
//output: 'y'

originalStr.slice(4,-11)
//output: ''

originalStr.slice(-11,-4)
//output: 'y Mount'

Do note that you can't start slicing after or before the string starts, if you try that you'll also get an empty string.

let originalStr = 'Candy Mountain!'

originalStr.length
//output: 15

originalString.slice(14)
//output: '!'

originalString.slice(15)
//output: ''

originalString.slice(999)
//output: ''

Substring

Substring() is preeeetty much like slice(), they're like twins with different quirks.

Where they are the same:

  • In either slice() or substring(), if your end index is not provided then your new string will copy the characters from the start index to the end of the original string
let originalStr = 'Candy Mountain!'

originalStr.slice('3')
//output: 'dy Mountain!'
originalStr.substring('3')
//output: 'dy Mountain!'

originalStr.substring(3)
//output: 'dy Mountain!'
originalStr.slice(3)
//output: 'dy Mountain!'
  • In either slice() or substring(), if both indexes provided are equal then an empty string is returned
let originalStr = 'Candy Mountain!'

originalStr.substring(2,2)
//output: ''
originalStr.slice(2,2)
//output: ''

However, where slice() took in negative integers and just counted them backwards from the end of the string, substring() will just consider them to be 0.

let originalStr = 'Candy Mountain!'

originalStr.slice(2,-2)
//output: 'ndy Mountai'

originalStr.substring(2,-2)
//output: 'Ca'

That does highlight another difference between substring() and slice(), though! While slice() required your start index to NOT be greater than your end index, substring() will just... swap them!

let originalStr = 'Candy Mountain!'

originalStr.substring(2,0)
//output: 'Ca'

originalStr.slice(2,0)
//output: ''

originalStr.slice(7,2)
//output: ''
originalStr.substring(7,2)
//output: 'ndy M'

Think of it as not actually slicing the string into pieces, but just grabbing characters between two positions. If I must grab between positions 2 and 7, or between 7 and 2 it makes no difference to substring().

Missing the counting backwards a bit, but can't deny substring() is a great guy!

Substr

substr() takes a start index and an optional length for your returned string.

originalStr = 'Candy Mountain!'

originalStr.substr(2,5)
//output: 'ndy M'

IT IS DEPRECATED, THOUGH. DON'T USE IT. DON'T. IT MIGHT GO POOF AT ANY TIME AND THEN YOU'LL HAVE TO GO THROUGH ALL YOUR CODEBASE AND REPLACE IT. STAY AWAY, BEWARE!

To have a similar functionality, try this:

string.substring(index, length + index);

originalStr = 'Candy Mountain!'

originalStr.substring(2, 5 + 2)
//output: 'ndy M'

//The old deprecated substr():
originalStr.substr(2,5)
//output: 'ndy M'

//Now into a whole function!
function notSubStr(string, index, length){
    return string.substring(index, length + index);
}

notSubStr(originalStr, 2, 5)
//output: 'ndy M'

Now that's been a lot of string slicing and cutting and pasting!

Put them into practice

Try these 8-kyu Codewars katas if you want a little practice: