4
\$\begingroup\$

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");
\$\endgroup\$

3 Answers 3

9
\$\begingroup\$
  1. 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.

  2. 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.

  3. 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"));

\$\endgroup\$
3
  • 5
    \$\begingroup\$ Don't you like a single i as a variable? ;-) \$\endgroup\$
    – t3chb0t
    Commented Jul 4, 2016 at 8:29
  • \$\begingroup\$ @t3chb0t It's just a thing of the past, which I keep because... I'm a romantic person. Using "ii" rather than "i" would help telling it's not the figure "1", as well as searching loop counters in basic text editors. Nowadays, it's not so good an idea to use it, I guess. \$\endgroup\$
    – Elegie
    Commented Jul 4, 2016 at 11:10
  • \$\begingroup\$ Also strict mode would prevent things like signing to undeclared variables. \$\endgroup\$
    – gcampbell
    Commented Jul 4, 2016 at 15:27
7
\$\begingroup\$

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/

\$\endgroup\$
0
0
\$\begingroup\$

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.

  1. Create an empty string called reversed.
  2. for each character in the provided string
  3. Take the character and add it to the start of reversed
  4. return the variable of reversed

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 characters 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');
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.