Objective
Create two variants of a function to split a given string at a given delimiter.
Difficulty
Description
Splitting a string into an array of substrings is an extremely common task while working with them.
The split()
string method is used in this regard. It accepts a delimiter string which specifies exactly where we wish to split the main string at.
For instance, given the string 'a|b|c'
, if we split it with '|'
as delimiter, we'd get the array ['a', 'b', 'c']
. See how the delimiter itself is chopped off from the main string with the remaining substring bits held on in an array.
As another example, if given the string 'a, b, c,d'
, and the delimiter ', '
(with the space character included), then splitting the string at this delimiter would yield the array ['a', 'b', 'c,d']
(comprised of 3 elements).
Simple?
In this exercise, you have to define two variants of a function stringSplit()
that splits a string into an array of substrings, at a given delimiter.
These variants are detailed as follows.
Variant 1
In the first variant, it must be assumed that the delimiter is not more than 1 character in length.
Shown below are a couple of examples of this function:
stringSplit('a|b|c', '|')
['a', 'b', 'c']
stringSplit('a b c', ' ')
['a', 'b', 'c']
stringSplit('a, b, c', '')
['a', ',', ' ', 'b', ',', ' ', 'c']
Note that if the given delimiter is an empty string, the function must return back an array of all the characters, as in the last statement above.
Variant 2
In the second variant, the delimiter string could be of any arbitrary length.
This is a more general implementation of a string splitting algorithm than the one above where we assumed that the delimiter is either ''
or comprised of just one character.
Shown below are a couple of examples:
stringSplit('a||b||c', '||')
['a', 'b', 'c']
stringSplit('a : b : c', ' : ')
['a', 'b', 'c']
stringSplit('aZZZbZZZc', 'ZZZ')
['a', 'b', 'c']
stringSplit('aZZZbZZZc', 'ZZ')
['a', 'Zb', 'Zc']
stringSplit('a, b, c', '')
['a', ',', ' ', 'b', ',', ' ', 'c']
Note that, as with the first variant, if the given delimiter is an empty string, the function must return back an array of all the characters.
New file
Inside the directory you created for this course on JavaScript, create a new folder called Exercise-18-String-Split and put the .html solution files for this exercise within it.
Solution
Before we delve into dealing with a given variant of stringSplit()
, let's first set up the basic wireframe of the function, i.e. its parameters, its return value, and so on.
Here's the definition:
function stringSplit(str, delimiter) {
// Code to go here.
}
Both the variants have the same signature, hence we could keep using this same definition for both of them.
In addition to this, there is a common case between them, which we could also solve right now, as we set up the basic structure of the function before focusing on one particular variant.
That common case is when the delimiter is an empty string, whereby we ought to return back an array of the characters of the string.
This case is addressed below:
function stringSplit(str, delimiter) {
var substrings = [];
if (delimiter === '') {
for (var i = 0, len = str.length; i < len; i++) {
substrings.push(str[i]);
}
return substrings;
}
}
First we check if delimiter is empty and if it is, we iterate over the string str
and push each character to the array substrings
.
Variant 1
In variant 1 of stringSplit()
, we need to assume that delimiter
is comprised of just one character (we've already addressed the empty delimiter case above, so that doesn't concern us now).
This largely simplifies the string splitting algorithm.
Anyways, the way we need to approach this problem is as follows: iterate over each character of str
, looking for delimiter
. When delimiter
is found, slice the substring before it starting at a given position and stash it into the substrings
array.
Obviously, we've left some details in this description, but you hopefully get the idea.
The most important thing here is to use an index-tracking variable that helps us determine the position from where we have to slice a substring, in the occasion when delimiter
is found. Let's call this variable index
.
This can be best understood with the help of an example.
Let's suppose that the string str
is 'js:cpp:py'
and delimiter
is ':'
. Initially, index = 0
.
The figure below shows the first occasion when the delimiter :
is found in the string str
:

At this stage, a substring is extracted from str
from index 0
(inclusive) to the index where delimiter
is found, i.e. 2
(exclusive). This substring is 'js'
.
Now, since at a subsequent match of delimiter
, we need to slice str
starting at the index right after the one where its last match was found, we need to update the index-tracking variable to 3
. (We don't update it to 2
since the delimiter itself doesn't have to be included in the substring extracted.)
The figure below shows the second occasion when the delimiter :
is found in str
:

At this stage, a substring is extracted from str
starting at index 3
, i.e. the current value of index
, and ending at index 6
(exclusive). This substring is 'cpp'
.
The index-tracking variable index
is updated to 7
.
After this point, the search for delimiter
continues uptil the end of str
, but no match is found. In the end, a final substring is extracted starting at index 7
and going all the way to the end of the string.

This yields the substring 'py'
.
And this completes our splitting, yielding the three substrings 'js'
, 'cpp'
and 'py'
.
Alright, so now is the time to implement this variant of stringSplit()
in code.
Here's the complete code:
function stringSplit(str, delimiter) {
var substrings = [];
var len = str.length;
if (delimiter === '') {
for (var i = 0; i < len; i++) {
substrings.push(str[i]);
}
return substrings;
}
var index = 0; // The index-tracking variable.
for (var i = 0; i < len; i++) {
if (str[i] === delimiter) {
substrings.push(str.slice(index, i));
index = i + 1;
}
}
substrings.push(str.slice(index));
return substrings;
}
Note that we have taken the declaration of the variable len
out of the body of the first if
statement. This is because len
is needed in the second for
loop as well, and so declaring it at the start of the function makes the code more readable and intuitive.
Perfect.
Let's move over to implementing variant 2.
Variant 2
Implementing the second variant of stringSplit()
is a little bit intimidating.
It requires us to add a second variable into our algorithm which holds the length of the delimiter
string. This variable will be used in the splitting algorithm to determine where to start searching for delimiter
up next when one match is found. Let's call it delimiterLength
.
Now since delimiter
is not just a one-character string, we ought to search for it in str
. This can very easily be done using the indexOf()
method.
We could use a while
loop that goes over str
until indexOf()
yields -1
indicating that there are no further matches of delimiter
in str
.
The second parameter of indexOf()
would come in handy here. We'd pass it the value of the index-tracking variable so as to search beyond the position where the last match of delimiter
was found.
In the end, when the while
loop completes, we'd extract a final substring from str
, just as we did in the stringSplit()
variant above.
Let's consider a sequence of illustrations to understand this better, as we saw above.
Suppose that str
is 'java:::ruby:::perl'
and delimiter
is ':::'
. Initially, index = 0
(the index-tracking variable).
The figure below shows the first occasion when the delimiter :::
is found in str
:

At this stage, a substring is extracted from str
starting at index 0
, i.e. the current value of index
, and ending at index 4
(exclusive), i.e. where the delimiter is found. This substring is 'java'
.
The index-tracking variable index
is updated to 7
, which is obtained by adding 3
, i.e. the value of delimiterLength
, to 4
.
The figure below shows the second occasion when the delimiter's match is found in str
:

A substring is extracted from str
starting at index 7
, i.e. the current value of index
, and ending at index 11
(exclusive). This substring is 'ruby'
.
The variable index
is updated to 14
, which is obtained by adding 3
, i.e. the value of delimiterLength
, to 11
.
Beyond this point, no match of delimiter is found in str
. Hence, our iteration ends, and as stated above, as the final step, we extract a substring from str
starting at index
and going all the way to the end of the string.
The figure below illustrates this:

As underlined in the figure, the substring extracted is 'perl'
.
And this completes our splitting, yielding the three substrings 'java'
, 'ruby'
and 'perl'
.
Simple?
It's time to implement this variant. Here's the code:
function stringSplit(str, delimiter) {
var substrings = [];
var len = str.length;
if (delimiter === '') {
for (var i = 0; i < len; i++) {
substrings.push(str[i]);
}
return substrings;
}
var index = 0; // The index-tracking variable.
var indexOfValue; // The value returned by indexOf().
var delimiterLength = delimiter.length;
while ((indexOfValue = str.indexOf(delimiter, index)) !== -1) {
substrings.push(str.slice(index, indexOfValue));
index = indexOfValue + delimiterLength;
}
substrings.push(str.slice(index));
return substrings;
}
The while
loop continues executing as long as str.indexOf(delimiter, index)
doesn't return -1
, which means that there is no further match of delimiter
in str
.
In each iteration, a substring is extracted from str
starting at the index index
(inclusive) and ending at indexOfValue
(exclusive), i.e. the index where the match of delimiter
is found.
Afterwards, index
is updated to the position right after the currently-matched delimiter
in str
, which employs the delimiterLength
variable.
Once the loop exits, a final substring extraction is made, starting from the index index
upto the end of str
. In the end, the array of substrings substrings
is returned.
And with this, we complete this exercise.