Problem
I have to reverse a string in JavaScript and cannot use the built in reverse()
function. It does not seem efficient to have to create two arrays but is there a better way?
function reverseString(str) {
newarr = str.split("");
result = [];
x = newarr.length;
for (i = x; i > -1; i--) {
result.push(newarr[i]);
}
str = result.join("");
return str;
}
reverseString("hello");
Solution
-
One array to rule them all
You do not need to create two arrays; one is enough. Simply swap slots until you’ve reached the “middle” of the array.
-
Declare your variables
It is better to use the
var
keyword to define your variables. Otherwise, they are declared on the top-level scope, i.e; they become global, and may be accessed and modified by other functions. -
Why not use
reverse()
?You do not say why you cannot use built-in functions. If you happen to have some base code which overrides native functions, then some groaning and roaring is in order.
function reverse(str) {
var chars = str.split("");
var length = chars.length;
var half = length / 2;
for (var ii = 0; ii < half; ii++) {
var temp = chars[ii];
var mirror = length - ii - 1;
chars[ii] = chars[mirror];
chars[mirror] = temp;
}
return chars.join("");
}
console.log(reverse("abcd"));
console.log(reverse("abcde"));
I was wondering if there’s a need to split at all, because characters are accessible directly using String#charAt
.
This implementation (which is almost the same as yours – only with the split) should be among the fastest.
function reverse(str) {
var result = [];
for (var i = str.length - 1; i >= 0; i--) {
result.push(str.charAt(i));
}
return result.join("");
}
console.log(reverse("abcde"));
According to some benchmark, String concatenation is better optimized than Array.join
, it also makes the code cleaner:
function reverse(str) {
var result = "";
for (var i = str.length - 1; i >= 0; i--) {
result += str.charAt(i);
}
return result;
}
console.log(reverse("abcde"));
As a side-note, you can get creative by using Array.prototype.reduce
and allow JavaScript duck-type the String
as an Array
.
function reverse(str) {
return Array.prototype.reduce.call(str, function(result, c) {
return c + result;
}, "");
}
console.log(reverse("Hello world!"));
And going further you can make an ES6 one-liner:
let reverse = str => Array.prototype.reduce.call(str, (result, c) => c + result, "");
console.log(reverse("Hello world!"));
JSFiddle forked from @Andreas: https://jsfiddle.net/kazenorin/6shbv6hs/2/
Right, so don’t use the reverse()
helper because it would make the algorithm solution too easy.
Every solution thus far has made use of the for
loop, excellent. I don’t like using it anyway.
I was going to use the reduce()
helper, but that was taken.
Alright, so instead I will use a different type of for
loop introduced with ES2015, called the for...of
syntax.
- Create an empty string called
reversed
. for
eachcharacter
in the provided string- Take the
character
and add it to the start ofreversed
return
the variable ofreversed
You are dying to see the code aren’t you.
function reverse(str) {
let reversed = '';
for (let character of str) {
reversed = character + reversed;
}
return reversed;
}
reverse('abc');
So what’s going on here? We say for
a variable declaration, I am creating a temporary variable that is redeclared every single time through this loop of character
:
for (let character of str) {
reversed = character + reversed;
}
Then we say of
and then the iterable object we want to iterate through, in this case its all the character
s of str
variable.
So we iterate through each character
of str
, one by one, and set each character
equal to the temporary variable of character
.
We then take that character
, add it to the start of the string reversed
and after the entire for
loop, we return
the string reversed
.
function reverse(str) {
let reversed = '';
for (let character of str) {
reversed = character + reversed;
}
return reversed;
}
reverse('abc');