56

I'm trying to reverse an input string

var oneway = document.getElementById('input_field').value();
var backway = oneway.reverse();

but firebug is telling me that oneway.reverse() is not a function. Any ideas?

Thank you

John
  • 1
  • 13
  • 98
  • 177
drummer
  • 1,211
  • 3
  • 16
  • 16

18 Answers18

122

reverse() is a method of array instances. It won't directly work on a string. You should first split the characters of the string into an array, reverse the array and then join back into a string:

var backway = oneway.split("").reverse().join("");

Update

The method above is only safe for "regular" strings. Please see comment by Mathias Bynens below and also his answer for a safe reverse method.

Community
  • 1
  • 1
Ates Goral
  • 137,716
  • 26
  • 137
  • 190
  • 24
    This is broken for strings that contain astral Unicode symbols, i.e. characters outside of the Basic Multilingual Plane. It will also give funny results for strings containing combining characters, e.g. a diaeresis might appear on the following character. The first issue will lead to ‘invalid’ strings (with the surrogate pairs for any astral symbols in the wrong order), the second to valid strings that look funny. My answer has a solution for both issues: http://stackoverflow.com/a/16776380/96656 – Mathias Bynens May 27 '13 at 15:35
80

The following technique (or similar) is commonly used to reverse a string in JavaScript:

// Don’t use this!
var naiveReverse = function(string) {
    return string.split('').reverse().join('');
}

In fact, all the answers posted so far are a variation of this pattern. However, there are some problems with this solution. For example:

naiveReverse('foo  bar');
// → 'rab �� oof'
// Where did the `` symbol go? Whoops!

If you’re wondering why this happens, read up on JavaScript’s internal character encoding. (TL;DR: is an astral symbol, and JavaScript exposes it as two separate code units.)

But there’s more:

// To see which symbols are being used here, check:
// http://mothereff.in/js-escapes#1ma%C3%B1ana%20man%CC%83ana
naiveReverse('mañana mañana');
// → 'anãnam anañam'
// Wait, so now the tilde is applied to the `a` instead of the `n`? WAT.

A good string to test string reverse implementations is the following:

'foo  bar mañana mañana'

Why? Because it contains an astral symbol () (which are represented by surrogate pairs in JavaScript) and a combining mark (the in the last mañana actually consists of two symbols: U+006E LATIN SMALL LETTER N and U+0303 COMBINING TILDE).

The order in which surrogate pairs appear cannot be reversed, else the astral symbol won’t show up anymore in the ‘reversed’ string. That’s why you saw those �� marks in the output for the previous example.

Combining marks always get applied to the previous symbol, so you have to treat both the main symbol (U+006E LATIN SMALL LETTER N) as the combining mark (U+0303 COMBINING TILDE) as a whole. Reversing their order will cause the combining mark to be paired with another symbol in the string. That’s why the example output had instead of ñ.

Hopefully, this explains why all the answers posted so far are wrong.


To answer your initial question — how to [properly] reverse a string in JavaScript —, I’ve written a small JavaScript library that is capable of Unicode-aware string reversal. It doesn’t have any of the issues I just mentioned. The library is called Esrever; its code is on GitHub, and it works in pretty much any JavaScript environment. It comes with a shell utility/binary, so you can easily reverse strings from your terminal if you want.

var input = 'foo  bar mañana mañana';
esrever.reverse(input);
// → 'anañam anañam rab  oof'
Mathias Bynens
  • 144,855
  • 52
  • 216
  • 248
9
String.prototype.reverse = function () {
    return this.split("").reverse().join("");
}

Inspired by the first result I got when I did a Google for javascript string reverse.

Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
4

Google harder, bros. This is by Edd Mann.

function reverse (s) {
for (var i = s.length - 1, o = ''; i >= 0; o += s[i--]) { }
return o;
}

http://eddmann.com/posts/ten-ways-to-reverse-a-string-in-javascript/

http://jsperf.com/string-reverse-function-performance

Mr. X
  • 41
  • 1
  • 1
    This is the fastest one of them all! I tried to match it with a while loop, but alas I could not beat the performance of this. http://jsperf.com/string-reverse-methods-performance –  Jun 19 '13 at 21:59
  • EDIT: Actually I lied, I was able to beat that by modifying it a little. =) –  Jun 19 '13 at 22:17
3

reverse is a function on an array and that is a string. You could explode the string into an array and then reverse it and then combine it back together though.

var str     = '0123456789';
var rev_str = str.split('').reverse().join('');
Alex Sexton
  • 10,401
  • 2
  • 29
  • 41
3
// You could reverse a string without creating an array

String.prototype.reverse= function(){
 var s= '', L= this.length;
 while(L){
  s+= this[--L];
 }
 return s;
}

var s1= 'the time has come, the walrus said, to speak of many things';
s1.reverse()
/*returned value: (String)
sgniht ynam fo kaeps ot, dias surlaw eht, emoc sah emit eht
*/
Daniel Imms
  • 47,944
  • 19
  • 150
  • 166
kennebec
  • 102,654
  • 32
  • 106
  • 127
2

This is probably the way, acceptable for all browsers:

function reverse(s) {
  var o = '';
  for (var i = s.length - 1; i >= 0; i--)
    o += s[i];
  return o;
}

Call it like a charm:

reverse('your_string');
Umair Hamid
  • 3,509
  • 3
  • 23
  • 25
2

I like to share some notable implementations for string reverse.

  1. split,reverse,join
const reverseString = (str) => str.split('') .reverse() .join('');
  1. reduce
const reverseString =(str) => [...str].reduce((acc, cur) => cur + acc);
  1. append last one by one

const reverseString = (str) => {
    const ary = [];
    for(let char of str) {
        ary.unshift(char);
    }
    return ary.join('');
}

  1. recursion
const reverseString =(str)=> (str === '') ? '' : reverseString(str.substr(1)) + str[0];
  1. two pointer approach
const reverseString = (str) =>  {
    const strArr = Array.from(str);
    let start = 0;
    let end = str.length - 1;    
    while (start <= end) {
        const temp = strArr[start];
        strArr[start] = strArr[end];
        strArr[end] = temp;
        start++;
        end--;
    }
    return strArr.join("");
}

//Using reverse with split, reverse , join
function reverseString1(str) {
  return str
    .split('') // alternative [...str], Array.from(str)
    .reverse() // alternative .sort(() => -1)
    .join('');
}

// Using reduce 
function reverseString2(str) {
      return [...str].reduce((accumulator, current) => current + accumulator) // reduce from left to right
  //alternative [...str].reduceRight((accumulator, current) => accumulator + current); // reduce right to left
}

// append to last one by one
function reverseString3(str){
    const ary = [];
    for(let char of str) {
        ary.unshift(char);
    }
    return ary.join('');
}

// recursion with ternary with substr 
function reverseString4(str) {
    return (str === '') ? '' : reverseString4(str.substr(1)) + str[0];
}


// two pointer approach [less time complexity O(n)] 
// front back chars exchanging
function reverseString5(str) {
    const strArr = Array.from(str); // alternative [...str],str.split('')
    let start = 0;
    let end = str.length - 1;    
    while (start <= end) {
        const temp = strArr[start];
        strArr[start] = strArr[end];
        strArr[end] = temp;
        start++;
        end--;
    }
    return strArr.join("");
}


console.log(reverseString1("Hello World"))
console.log(reverseString2("Hello World"))
console.log(reverseString3("Hello World"))
console.log(reverseString4("Hello World"))
console.log(reverseString5("Hello World"))
//=> dlroW olleH

Note: Built-in method works well for ASCII inputs, not unicode things.. so use spread operation inspite of split. Check out split vs spread implementation

Extra: In-Place string reverse is not possible in JS. Check out in-place reverse

1
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script>


        $(document).ready(function () {

            $("#stringInput").keyup(function () {
                debugger;
                var string = $("#stringInput").val();
                var stringArray = [];
                sInput = string.toString();

                for (var i = 0, len = sInput.length; i < len; i++) {

                    stringArray.push(sInput.charAt(i));
                }
                stringArray.reverse();
                str = stringArray.join('');


                document.getElementById("stringOutput").value = str;

            });

            $("button").click(function () {
                debugger;
                $("#myForm").toggle();
            });
        });

    </script>
</head>

<body>

     <div>
        <form name="myForm" id="myForm">

    <table>
        <tr>
            <td>Insert Elements :</td>
            <td><input type="text" name="stringInput" id="stringInput"/></td>

            <td>Output :</td>
            <td><input type="text" id="stringOutput" name="stringOutput" readonly="true" /></td>
        </tr>

    </table>
      </form>
         <button>Show/Hide</button>
    </div>
</body>
</html>
Mayur Narula
  • 150
  • 1
  • 4
1

Reverse String using function parameter with error handling :

function reverseString(s) 
{
   try
   {
      console.log(s.split("").reverse().join(""));
   }
   catch(e)
   {
      console.log(e.message);
      console.log(s);
   }   
}
0

I think you'll find that in fact reverse() isn't a function in jQuery. Incidentally, jQuery is really good at manipulating your DOM, but isn't really for string manipulation as such (although you can probably get plugins/write your own) to do this.

The best way I've found to reverse a string in javascript is to do the following:

String.prototype.reverse = function(){
splitext = this.split("");
revertext = splitext.reverse();
reversed = revertext.join("");
return reversed;
}

Found at: http://www.bytemycode.com/snippets/snippet/400/

I think you'll find that if you pop the above into your code somewhere, your call to .reverse() should work :)

Iain Fraser
  • 6,578
  • 8
  • 43
  • 68
0

Mathias Bynens, your code works grate, thanks a lot!

I convert your code to a function, in this way users are able to copy it from here.

Thanks!

//The function reverse a string,  JavaScript’s has internal character encoding so we are
//unable to reverse the string in the "easy ways". For example the TL;DR:  is an astral
//symbol, and JavaScript exposes it as two separate code units.
function ReverseString(string){
    //-
    var regexSymbolWithCombiningMarks = /([\0-\u02FF\u0370-\u1DBF\u1E00-\u20CF\u2100-\uD7FF\uDC00-\uFE1F\uFE30-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF])([\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]+)/g;
    var regexSurrogatePair = /([\uD800-\uDBFF])([\uDC00-\uDFFF])/g;
    //-

    //Step 1: deal with combining marks and astral symbols (surrogate pairs)
    string = string
        //Swap symbols with their combining marks so the combining marks go first
        .replace(regexSymbolWithCombiningMarks, function($0, $1, $2) {
            return reverse($2) + $1;
        })
        // Swap high and low surrogates so the low surrogates go first
        .replace(regexSurrogatePair, '$2$1');

    // Step 2: reverse the code units in the string
    var result = '';
    var index = string.length;
    while (index--) {
        result += string.charAt(index);
    }

    //Return value
    return result;
}
Roy Shoa
  • 3,117
  • 1
  • 37
  • 41
0

This reverse prototype function is implemented using "this". If you see log console of "this", it will generate the array, and it has length property. So that it!!! Just use reverse "for-loop" as shown in the code snippet.

String.prototype.reverse = function () {
    console.log(this);
    var result = "";
    var len = this.length;
    
    for (i = (len-1); i >= 0 ; i--) {
        result += this[i];
    }
    return result;
};

alert("elahnu jaknap".reverse());
  • Better not change objects you don't own: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain#Bad_practice.3A_Extension_of_native_prototypes – HMR Nov 06 '14 at 09:48
0

Use this simple method to reverse the words of a string at its position

 function fun(str){
     var arr1=str.split(' ');
     console.log(arr1);
     var strings='',rever='';
     for(var i=0;i<arr1.length;i++)
     {
        strings=arr1[i].split('');
        rever+=strings.reverse().join('')+' ';  
     }
     console.log(rever.split(' '));
     console.log(rever.trim());
 };
 fun('javascript is fun');
Nikolay Mihaylov
  • 3,868
  • 8
  • 27
  • 32
0

If it's necessary to revert the string, but return the original value of the error:

function reverseString(s) {
    let valuePrintS;
    try {
        valuePrintS = s.split("").reverse().join("");    
    } catch {
        console.log("s.split is not a function");
        valuePrintS = s;
    } finally {
        console.log(valuePrintS);
    }
}
0

I believe most performant solution with reduce like in https://stackoverflow.com/a/68978553/5018572 post

function reverse(str) {
  return str.split("").reduce((final, letter) => letter + final);
}

console.log(reverse("Armaggedon"));
Halil Kayer
  • 350
  • 3
  • 8
0

This is how I always do;

var rev = Array.prototype.reduce.call("Hello World",(p,c) => c+p);
console.log(rev);

Some people do it like [].prototype.redu... but that would be creating an array for no reason. Instead use the Array constructor.

Also some people ask why Array.prototype.reverse.call("Hello World") wouldn't work. It's so because .reverse() attempts to reverse the subject array in place and with immutable values in JS such as a String you can not do that.

Redu
  • 25,060
  • 6
  • 56
  • 76
-1
String.prototype.strReverse = function() {

    var newstring = "";

    for (var s=0; s < this.length; s++) {
        newstring = this.charAt(s) + newstring;
    }

    return newstring;
};
Juliano Alves
  • 2,006
  • 4
  • 35
  • 37
Abhi
  • 1