Exercise: Reversing a string in JavaScript


In this article, you will find different ways to reverse a string. Attempt to solve this exercise alone, and run the code in the below terminal.

Even if your solution is successful, I suggest reading all the solutions.

Exercise

Exercise: Write a reverse function that reverses its string argument.

The console.log expression should write the ecitcarP ni 6SE message to the console.

Your solution: reversing a string

Write your solution here.

const text = 'ES6 in Practice';

const reverse = str => {
// write your solution here
}

console.log(reverse(text));

Problem

JavaScript strings don't have a reverse method. Only arrays can be reversed like this:

If you try to reverse a text, it won't work:

Planning the solution

When you attempt to pass a coding intervies, expect the exercise to be underspecified. This means that you have to ask questions to clarify any ambiguities.

For instance, you might correctly solve the string reversal exercise, just to find out that a test case calls your solution with null, {}, 52 etc.

If your solution returns "[object Object]", you have to explain why you think this is the intended answer.

However, if your solution throws an error like the one below, you may be in trouble.

Your approach may change depending on the answer:

  • you can convert the input to a string,
  • you can return a specific value such as null,
  • you can just allow an error to be thrown.

Regardless of the approach, make sure you clarify how your program will react to errors before solving the exercise.

We will choose the last approach: errors to be thrown when the input is incorrect. This allows us to focus just on the reversal.

Reversing a string using the array reverse method

The first solution relies on the reverse method of arrays:

It is always important create a plan before writing code. I am illustrating this plan on this easy exercise. If you develop this habit, you will be able to solve harder interview exercises in the same way.

Let's see the solution step by step:

By using chaining, you can write these three instructions in just one statement:

Remark: in general, when chaining calls after each other, writing each method call in a new line results in more readable code. Exceptions apply. For instance, the below code is fairly readable:

Let's create the function reversing a string:

If the body of a function can be summed up in a simple reverse statement, it makes sense to drop the braces and the return statements and just stick to describing the input => returnValue correspondance with the arrow function:

Simplifying the reversal with the Spread operator

We can write this function in an even more compact way if we use the spread operator to enumerate the characters of the input character by character:

Reversing an array with reduce

In the unlikely case you didn't find the reverse method of arrays, but you know how to use the reduce higher order function, you can enumerate the characters of the string and build the return value from right to left:

Of course if you are more comfortable with the ES5 syntax, during the interview, you can simply write old style functions:

I highly recommend learning the ES6 syntax though, as it is a basic expectation in 2020.

Reversing an array iteratively and with recursion

If everything else fails, you can go back to the basic building blocks of JavaScript: sequence, selection, iteration, and functions. You can write loops and function calls to get the solution.

The alternative is to think recursively.

Reversing a string of length 1 or less is obvious: we just return the string.

Reversing a string of larger length works as follows:

  1. Take the head and the tail of the string. The head is the first character, the tail consists of the remaining characters.
  2. Reverse the tail.
  3. Add the head to the end of the reversed string.

Obviously, the reversal can be written in just one statement:

However, for readability sake, it makes more sense sticking to the readable solution.

Using the fact that strings are iterables, you can also use pattern matching (destructuring) to write a neat solution:

In this solution, you have to explain when your values are of type string and when they are arrays. This is a complicated solution. The price we pay for this solution is that it results in an incorrect answer when called with the empty string:

Make sure you don't try to show off by appearing too smart, because it can easily backfire.

In this specifi example, you can change the exit condition to make the code work:

Don't forget that recursive function calls are resource intensive, because they occupy space on the stack. By using recursion, even a constant space complexity solution becomes linear, if we have to iterate on the whole input due to the function call stack.

Therefore, it is advisable to turn recursive solutions into iterative ones.

What about long unicode characters?

Reversing a string sounds too easy, right? Well, now comes the test. Try to reverse the following string:

For a list of emojis, check out emojipedia.org.

Let's test all our solutions in separate blocks. I added blocks in this example to separate the namespaces so that we can define our reverse function over and over again:

What is the problem with long unicode characters?

As written in ES6 in Practice, long unicode characters need special care. The rule of thumb is that you should use ES6 features to treat strings. ES5 features are often unsafe, becasue they don't take into consideration that characters may have different lengths.

Safe language constructs:

  • [...str]
  • for ( let ch of str ) {...}

Unsafe language constructs:

  • iteration based on str.length: '😅'.length is 2, while '孫'.length is 1
  • str.slice(startIndex)
  • str.substr(startIndex)
  • for ( let index in str ) {...}
  • many others

Summary

Reversing a string seems very easy at first glance. However, there are many traps and pitfalls that you have to consider. Make sure you use safe ES6 code so that you can reverse any string, including emojis.