Wie kann man eine in JavaScript vorhandene Zeichenfolge umkehren?


433

Wie umkehren Sie eine Zeichenfolge an Ort und Stelle (oder in-place) in JavaScript , wenn es um eine Funktion mit einer return - Anweisung übergeben wird, ohne Einbau-Verwendung von Funktionen ( .reverse(), .charAt()etc.)?


Sie dürfen also .charAt () nicht verwenden, um die Zeichen der Zeichenfolge abzurufen?
Irwin

155
Das kannst du nicht. JavaScript-Zeichenfolgen sind unveränderlich, was bedeutet, dass der jedem zugewiesene Speicher nicht beschrieben werden kann, was echte "In-Place" -Umkehrungen unmöglich macht.
Crescent Fresh


1
@crescentfresh sollten Sie das als neue Antwort posten.
Baudtack

Antworten:


735

Solange Sie mit einfachen ASCII-Zeichen arbeiten und gerne integrierte Funktionen verwenden, funktioniert dies:

function reverse(s){
    return s.split("").reverse().join("");
}

Wenn Sie eine Lösung benötigen, die UTF-16 oder andere Multi-Byte-Zeichen unterstützt, beachten Sie, dass diese Funktion ungültige Unicode-Zeichenfolgen oder gültige Zeichenfolgen liefert, die lustig aussehen. Vielleicht möchten Sie stattdessen diese Antwort berücksichtigen .

[... s] ist Unicode-fähig, eine kleine Bearbeitung ergibt: -

function reverse(s){
    return [...s].reverse().join("");
}

44
Dies gilt nicht für UTF-16-Zeichenfolgen, die Ersatzpaare enthalten, dh Zeichen außerhalb der mehrsprachigen Grundebene. Es gibt auch lustige Ergebnisse für Zeichenfolgen, die kombinierte Zeichen enthalten, z. B. kann eine Diaeresis auf dem folgenden Zeichen erscheinen. Das erste Problem führt zu ungültigen Unicode-Zeichenfolgen, das zweite zu gültigen Zeichenfolgen, die lustig aussehen.
Martin Probst

2
@Richeve Bebedor "Alles ohne Verwendung der integrierten Funktionen? .Reverse ()" Dies wäre keine akzeptierte Lösung, da es nicht in die Grenzen der Frage passt, obwohl es eine praktikable Lösung für das Umkehren eines Strings in JS ist.
David Starkey

1
@ DavidStarkey: Ja, wenn ich fast vier Jahre später darauf zurückblicke, ist es schwer zu sehen, wie sehr ich den Punkt der Frage so gründlich übersehen habe. Es sieht so aus, als hätte ich nur zwei Minuten warten und Crescentfreshs Kommentar zum ursprünglichen Beitrag positiv bewerten sollen!
Belacqua

14
@ MartinProbst Meine Antwort bietet eine Unicode-fähige Lösung für das Problem, das sich mit Ersatzpaaren
Mathias Bynens

1
Für UTF-16 return [...s].reverse().join("");kann funktionieren.
user4642212

410

Die folgende Technik (oder eine ähnliche) wird üblicherweise verwendet, um eine Zeichenfolge in JavaScript umzukehren:

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

Tatsächlich sind alle bisher veröffentlichten Antworten eine Variation dieses Musters. Es gibt jedoch einige Probleme mit dieser Lösung. Zum Beispiel:

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

Wenn Sie sich fragen, warum dies passiert, lesen Sie die interne Zeichenkodierung von JavaScript . (TL; DR: 𝌆ist ein Astralsymbol und wird von JavaScript als zwei separate Codeeinheiten verfügbar gemacht.)

Aber es gibt noch mehr:

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

Ein guter String zum Testen von String-Reverse-Implementierungen ist der folgende :

'foo 𝌆 bar mañana mañana'

Warum? Weil es ein Astralsymbol ( 𝌆) (das in JavaScript durch Ersatzpaare dargestellt wird ) und eine Kombinationsmarke enthält (die letzte mañanabesteht tatsächlich aus zwei Symbolen: U + 006E LATIN SMALL LETTER N und U + 0303 COMBINING TILDE).

Die Reihenfolge, in der Ersatzpaare erscheinen, kann nicht umgekehrt werden, da sonst das Astralsymbol nicht mehr in der "umgekehrten" Zeichenfolge angezeigt wird. Aus diesem Grund haben Sie diese ��Markierungen in der Ausgabe des vorherigen Beispiels gesehen.

Kombinationsmarken werden immer auf das vorherige Symbol angewendet, daher müssen Sie sowohl das Hauptsymbol (U + 006E LATIN SMALL LETTER N) als die Kombinationsmarke (U + 0303 COMBINING TILDE) als Ganzes behandeln. Durch Umkehren der Reihenfolge wird die Kombinationsmarke mit einem anderen Symbol in der Zeichenfolge gepaart. Deshalb hatte die Beispielausgabe statt ñ.

Hoffentlich erklärt dies, warum alle bisher veröffentlichten Antworten falsch sind .


Um Ihre erste Frage zu beantworten - wie man eine Zeichenfolge in JavaScript [richtig] umkehrt - habe ich eine kleine JavaScript-Bibliothek geschrieben, die eine Unicode-fähige Zeichenfolgenumkehr ermöglicht. Es hat keine der Probleme, die ich gerade erwähnt habe. Die Bibliothek heißt Esrever ; Der Code befindet sich auf GitHub und funktioniert in nahezu jeder JavaScript-Umgebung. Es wird mit einem Shell-Dienstprogramm / einer Binärdatei geliefert, sodass Sie Zeichenfolgen von Ihrem Terminal aus problemlos umkehren können, wenn Sie möchten.

var input = 'foo 𝌆 bar mañana mañana';
esrever.reverse(input);
// → 'anañam anañam rab 𝌆 oof'

Weitere Informationen zum „In-Place“ -Teil finden Sie in den anderen Antworten.


65
Sie sollten den Hauptteil des Codes von Esrever in Ihre Antwort aufnehmen.
r0estir0bbe

1
@ Meglio Mit diesem speziellen Ansatz, ja.
Mathias Bynens

8
Das Problem ist natürlich, dass "eine Zeichenfolge umkehren" eindeutig klingt, aber nicht angesichts der hier genannten Probleme. Gibt das Umkehren einer Zeichenfolge die Zeichenfolge zurück, die beim Drucken die Graphemcluster in der Zeichenfolge in umgekehrter Reihenfolge anzeigt? Einerseits klingt das wahrscheinlich. Auf der anderen Seite, warum sollten Sie das jemals tun wollen? Diese Definition hängt davon ab, ob sie gedruckt wird, und das Drucken einer umgekehrten Zeichenfolge ist selten sinnvoll. Als Teil eines Algorithmus können Ihre Anforderungen insgesamt unterschiedlich sein.
Martijn

19
Während dies eine tut große Aufgabe , das Problem zu erklären, die eigentliche Antwort ist in einem anderen Schloss . Wie @ r0estir0bbe vor über einem Jahr sagte, sollte der relevante Code in der Antwort enthalten sein, nicht nur verknüpft.
TJ Crowder

3
"Hoffentlich erklärt dies, warum alle bisher veröffentlichten Antworten falsch sind" - Diese Behauptung ist imo übermäßig eindringlich. Viele Anwendungsfälle erfordern keine UTF-16-Unterstützung (einfaches Beispiel; Arbeiten mit URLs und URL-Komponenten / -Parametern). Eine Lösung ist nicht "falsch", nur weil sie kein nicht erforderliches Szenario behandelt. Insbesondere erklärt die Antwort mit der höchsten Abstimmung ausdrücklich, dass sie nur mit ASCII-Zeichen funktioniert und daher definitiv nicht einmal ein bisschen falsch ist.
Aroth

92
String.prototype.reverse_string=function() {return this.split("").reverse().join("");}

oder

String.prototype.reverse_string = function() {
    var s = "";
    var i = this.length;
    while (i>0) {
        s += this.substring(i-1,i);
        i--;
    }
    return s;
}

Ich stimme dem String-Prototyp definitiv zu.
Jeff Meatball Yang

3
String-Verkettung ist teuer. Besser ein Array erstellen und verbinden oder concat () verwenden.
Björn

2
# 1 ist am besten, # 2 könnte schrecklich langsam sein
AdamJLev

9
Keine der beiden Lösungen funktioniert jedoch, wenn zusammengesetzte Unicode-Zeichen vorhanden sind.
Eric Grange

2
@JuanMendes Ich habe diesen Kommentar 2009 hinterlassen, die Dinge haben sich in den letzten 4 Jahren geändert. : P
Björn

62

Detaillierte Analyse und zehn verschiedene Möglichkeiten zum Umkehren einer Zeichenfolge und ihrer Leistungsdetails.

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

Leistung dieser Implementierungen:

Implementierung (en) mit der besten Leistung pro Browser

  • Chrome 15 - Implemationen 1 und 6
  • Firefox 7 - Implementierung 6
  • IE 9 - Implementierung 4
  • Opera 12 - Implementierung 9

Hier sind diese Implementierungen:

Implementierung 1:

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

Implementierung 2:

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

Implementierung 3:

function reverse(s) {
  var o = [];
  for (var i = 0, len = s.length; i <= len; i++)
    o.push(s.charAt(len - i));
  return o.join('');
}

Implementierung 4:

function reverse(s) {
  return s.split('').reverse().join('');
}

Implementierung 5:

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

Implementierung 6:

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

Implementierung 7:

function reverse(s) {
  return (s === '') ? '' : reverse(s.substr(1)) + s.charAt(0);
}

Implementierung 8:

function reverse(s) {
  function rev(s, len, o) {
    return (len === 0) ? o : rev(s, --len, (o += s[len]));
  };
  return rev(s, s.length, '');
}

Implementierung 9:

function reverse(s) {
  s = s.split('');
  var len = s.length,
      halfIndex = Math.floor(len / 2) - 1,
      tmp;


     for (var i = 0; i <= halfIndex; i++) {
        tmp = s[len - i - 1];
        s[len - i - 1] = s[i];
        s[i] = tmp;
      }
      return s.join('');
    }

Implementierung 10

function reverse(s) {
  if (s.length < 2)
    return s;
  var halfIndex = Math.ceil(s.length / 2);
  return reverse(s.substr(halfIndex)) +
         reverse(s.substr(0, halfIndex));
}

53

Das ganze "Reverse a String in Place" ist eine veraltete Interviewfrage, die C-Programmierer und Leute, die von ihnen interviewt wurden (vielleicht aus Rache?), Fragen werden. Leider funktioniert der Teil "An Ort und Stelle" nicht mehr, da Zeichenfolgen in nahezu jeder verwalteten Sprache (JS, C # usw.) unveränderliche Zeichenfolgen verwenden, wodurch die gesamte Idee, eine Zeichenfolge zu verschieben, ohne neuen Speicher zuzuweisen, zunichte gemacht wird.

Während die obigen Lösungen tatsächlich eine Zeichenfolge umkehren, tun sie dies nicht, ohne mehr Speicher zuzuweisen, und erfüllen daher nicht die Bedingungen. Sie müssen direkten Zugriff auf die zugewiesene Zeichenfolge haben und in der Lage sein, ihren ursprünglichen Speicherort zu ändern, um sie an Ort und Stelle umkehren zu können.

Persönlich hasse ich solche Interviewfragen wirklich, aber leider bin ich mir sicher, dass wir sie noch viele Jahre sehen werden.


7
Ich kann zumindest sagen, dass ich vor einiger Zeit einen Interviewer hatte, der ziemlich beeindruckt war, als er mich fragte, wie man eine Zeichenfolge "in-place" in JS umkehrt, und ich erklärte, warum dies unmöglich ist, da Zeichenfolgen in JS unveränderlich sind. Ich weiß nicht, ob das die Antwort war, die er erwartet hatte, oder ob ich ihn ein wenig erzogen habe. So oder so hat es gut geklappt;)
Chev

1
Vielleicht meint er "von einem Garbage Collector verwaltet", zumindest ist das normalerweise mit "verwalteter Sprache" oder dem Vorhandensein einer virtuellen Maschine / virtuellen Laufzeitumgebung gemeint? @ Torazaburo
AntonB

39

Verwenden Sie zuerst Array.from(), um eine Zeichenfolge in ein Array umzuwandeln, dann Array.prototype.reverse()um das Array umzukehren und es dann Array.prototype.join()wieder zu einer Zeichenfolge zu machen.

const reverse = str => Array.from(str).reverse().join('');

Es hat Overhead, aber das ist eine elegante Lösung! Die bereits vorhandene reverseLogik wird nicht umgeschrieben .
Gershom

2
@felixfbecker Nein, string.split('')funktioniert nicht. Weitere Erklärungen finden Sie in dieser Antwort .
Michał Perłakowski

5
Dies sollte die akzeptierte Antwort sein, da sie auch mit Unicode funktioniert. ZB aus dem obigen Beispiel:Array.from('foo 𝌆 bar mañana mañana').reverse().join('') == 'anãnam anañam rab 𝌆 oof'
Julian TF

3
@JulianTF Nicht genau, eine Tilde wird immer noch auf 'a' anstelle von 'n' angewendet.
Roman Boiko

2
@RomanBoiko Stimmt, aber Sie können die Zeichenfolge zuerst normalisieren. Array.from('foo 𝌆 bar mañana mañana'.normalize('NFC')).reverse().join('')wird"anañam anañam rab 𝌆 oof"
Herr Lister

26

In ECMAScript 6 können Sie eine Zeichenfolge noch schneller umkehren, ohne die .split('')Split-Methode zu verwenden. Der Spread-Operator lautet wie folgt:

var str = [...'racecar'].reverse().join('');

1
Mit ES6 können Sie auch zwei Backticks anstelle von('')

In diesem Fall gibt es keinen Grund, zwei Backticks zu verwenden
Vic

1
Wenn Sie nicht Code-Golf spielen, sollten Sie dies vermeiden. Schreiben string.split('')ist für die meisten Menschen klarer als [...string].
AnnanFay

1
@AnnanFay .split('')hat das Problem mit Zeichen aus den Zusatzebenen (Surrogatpaar in UTF-16), da sie von der UTF-16 - Code teilt Einheit anstatt Codepunkt . Der Spread-Operator und Array.from()(meine Präferenz) nicht.
Inkling

@Inkling Ich wusste nicht, dass das ein Problem war. Vielen Dank für den Hinweis. Ich wäre immer noch versucht, aus Gründen der Übersichtlichkeit eine Utility-Funktion zu schreiben.
AnnanFay

19

Scheint, als wäre ich 3 Jahre zu spät zur Party ...

Leider können Sie nicht, wie bereits erwähnt wurde. Siehe Sind JavaScript-Zeichenfolgen unveränderlich? Benötige ich einen "String Builder" in JavaScript?

Das nächstbeste, was Sie tun können, ist, eine "Ansicht" oder einen "Wrapper" zu erstellen, der eine Zeichenfolge verwendet und alle Teile der von Ihnen verwendeten Zeichenfolgen-API neu implementiert, aber so tut, als wäre die Zeichenfolge umgekehrt. Zum Beispiel:

var identity = function(x){return x};

function LazyString(s) {
    this.original = s;

    this.length = s.length;
    this.start = 0; this.stop = this.length; this.dir = 1; // "virtual" slicing
    // (dir=-1 if reversed)

    this._caseTransform = identity;
}

// syntactic sugar to create new object:
function S(s) {
    return new LazyString(s);
}

//We now implement a `"...".reversed` which toggles a flag which will change our math:

(function(){ // begin anonymous scope
    var x = LazyString.prototype;

    // Addition to the String API
    x.reversed = function() {
        var s = new LazyString(this.original);

        s.start = this.stop - this.dir;
        s.stop = this.start - this.dir;
        s.dir = -1*this.dir;
        s.length = this.length;

        s._caseTransform = this._caseTransform;
        return s;
    }

//We also override string coercion for some extra versatility (not really necessary):

    // OVERRIDE STRING COERCION
    //   - for string concatenation e.g. "abc"+reversed("abc")
    x.toString = function() {
        if (typeof this._realized == 'undefined') {  // cached, to avoid recalculation
            this._realized = this.dir==1 ?
                this.original.slice(this.start,this.stop) : 
                this.original.slice(this.stop+1,this.start+1).split("").reverse().join("");

            this._realized = this._caseTransform.call(this._realized, this._realized);
        }
        return this._realized;
    }

//Now we reimplement the String API by doing some math:

    // String API:

    // Do some math to figure out which character we really want

    x.charAt = function(i) {
        return this.slice(i, i+1).toString();
    }
    x.charCodeAt = function(i) {
        return this.slice(i, i+1).toString().charCodeAt(0);
    }

// Slicing functions:

    x.slice = function(start,stop) {
        // lazy chaining version of https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/slice

        if (stop===undefined)
            stop = this.length;

        var relativeStart = start<0 ? this.length+start : start;
        var relativeStop = stop<0 ? this.length+stop : stop;

        if (relativeStart >= this.length)
            relativeStart = this.length;
        if (relativeStart < 0)
            relativeStart = 0;

        if (relativeStop > this.length)
            relativeStop = this.length;
        if (relativeStop < 0)
            relativeStop = 0;

        if (relativeStop < relativeStart)
            relativeStop = relativeStart;

        var s = new LazyString(this.original);
        s.length = relativeStop - relativeStart;
        s.start = this.start + this.dir*relativeStart;
        s.stop = s.start + this.dir*s.length;
        s.dir = this.dir;

        //console.log([this.start,this.stop,this.dir,this.length], [s.start,s.stop,s.dir,s.length])

        s._caseTransform = this._caseTransform;
        return s;
    }
    x.substring = function() {
        // ...
    }
    x.substr = function() {
        // ...
    }

//Miscellaneous functions:

    // Iterative search

    x.indexOf = function(value) {
        for(var i=0; i<this.length; i++)
            if (value==this.charAt(i))
                return i;
        return -1;
    }
    x.lastIndexOf = function() {
        for(var i=this.length-1; i>=0; i--)
            if (value==this.charAt(i))
                return i;
        return -1;
    }

    // The following functions are too complicated to reimplement easily.
    // Instead just realize the slice and do it the usual non-in-place way.

    x.match = function() {
        var s = this.toString();
        return s.apply(s, arguments);
    }
    x.replace = function() {
        var s = this.toString();
        return s.apply(s, arguments);
    }
    x.search = function() {
        var s = this.toString();
        return s.apply(s, arguments);
    }
    x.split = function() {
        var s = this.toString();
        return s.apply(s, arguments);
    }

// Case transforms:

    x.toLowerCase = function() {
        var s = new LazyString(this.original);
        s._caseTransform = ''.toLowerCase;

        s.start=this.start; s.stop=this.stop; s.dir=this.dir; s.length=this.length;

        return s;
    }
    x.toUpperCase = function() {
        var s = new LazyString(this.original);
        s._caseTransform = ''.toUpperCase;

        s.start=this.start; s.stop=this.stop; s.dir=this.dir; s.length=this.length;

        return s;
    }

})() // end anonymous scope

Demo:

> r = S('abcABC')
LazyString
  original: "abcABC"
  __proto__: LazyString

> r.charAt(1);       // doesn't reverse string!!! (good if very long)
"B"

> r.toLowerCase()    // must reverse string, so does so
"cbacba"

> r.toUpperCase()    // string already reversed: no extra work
"CBACBA"

> r + '-demo-' + r   // natural coercion, string already reversed: no extra work
"CBAcba-demo-CBAcba"

Der Kicker - Folgendes wird vor Ort durch reine Mathematik erledigt, wobei jeder Charakter nur einmal und nur bei Bedarf besucht wird:

> 'demo: ' + S('0123456789abcdef').slice(3).reversed().slice(1,-1).toUpperCase()
"demo: EDCBA987654"

> S('0123456789ABCDEF').slice(3).reversed().slice(1,-1).toLowerCase().charAt(3)
"b"

Dies führt zu erheblichen Einsparungen, wenn Sie auf eine sehr große Zeichenfolge angewendet werden, wenn Sie nur eine relativ kleine Scheibe davon nehmen.

Ob sich dies lohnt (über das Umkehren als Kopie wie in den meisten Programmiersprachen), hängt stark von Ihrem Anwendungsfall ab und davon, wie effizient Sie die Zeichenfolgen-API erneut implementieren. Wenn Sie beispielsweise nur einen String-Index bearbeiten oder kleine slices oder substrs nehmen möchten , sparen Sie Platz und Zeit. Wenn Sie jedoch große umgekehrte Schnitte oder Teilzeichenfolgen drucken möchten, sind die Einsparungen möglicherweise gering und sogar noch schlimmer als bei einer vollständigen Kopie. Ihre "umgekehrte" Zeichenfolge hat auch nicht den Typstring , obwohl Sie dies möglicherweise mit Prototyping vortäuschen können.

Die obige Demo-Implementierung erstellt ein neues Objekt vom Typ ReversedString. Es ist ein Prototyp und daher ziemlich effizient mit nahezu minimalem Arbeitsaufwand und minimalem Platzaufwand (Prototypdefinitionen werden gemeinsam genutzt). Es ist eine träge Implementierung, die ein verzögertes Schneiden beinhaltet. Wann immer Sie eine Funktion wie .sliceoder .reversedausführen, wird eine Indexmathematik ausgeführt. Schließlich, wenn Sie Daten extrahieren (indem Sie implizit .toString()oder aufrufen.charCodeAt(...) etwas anderes), werden diese auf "intelligente" Weise angewendet, wobei die geringstmöglichen Daten berührt werden.

Hinweis: Die obige Zeichenfolgen-API ist ein Beispiel und möglicherweise nicht perfekt implementiert. Sie können auch nur 1-2 Funktionen verwenden, die Sie benötigen.


13

Es gibt viele Möglichkeiten, wie Sie eine Zeichenfolge in JavaScript umkehren können. Ich schreibe drei Möglichkeiten auf, die ich bevorzuge.

Ansatz 1: Umkehrfunktion verwenden:

function reverse(str) {
  return str.split('').reverse().join('');
}

Ansatz 2: Durchlaufen von Charakteren:

function reverse(str) {
  let reversed = '';

  for (let character of str) {
    reversed = character + reversed;
  }

  return reversed;
}

Ansatz 3: Verwenden der Reduktionsfunktion:

function reverse(str) {
  return str.split('').reduce((rev, char) => char + rev, '');
}

Ich hoffe das hilft :)


10

Während eines Interviews wurde ich gebeten, eine Zeichenfolge ohne Verwendung von Variablen oder nativen Methoden umzukehren. Dies ist meine Lieblingsimplementierung:

function reverseString(str) {
    return str === '' ? '' : reverseString(str.slice(1)) + str[0];
}

Kurz, einfach, aber langsam wie die Hölle;)
Tom

13
Keine nativen Methoden? Was ist mit slice? : - /
Blatt

1
Interessante Verwendung der Rekursion. Ironischerweise ist es auf Stack Overflow. stackoverflow.com/q/2805172/265877
Alex

@ Alex, du machst einen guten Punkt. In einigen Fällen werden Sie vom Interviewer gebeten, diese nicht zu verwenden Array.prototype.reverse().
Daniel

10

Es gibt mehrere Möglichkeiten, dies zu tun. Sie können Folgendes überprüfen:

1. Traditionell für Schleife (Inkrementieren):

function reverseString(str){
        let stringRev ="";
        for(let i= 0; i<str.length; i++){
            stringRev = str[i]+stringRev;
        }
        return stringRev;
}
alert(reverseString("Hello World!"));

2. Traditionell für Schleife (Dekrementierung):

function reverseString(str){
    let revstr = "";
    for(let i = str.length-1; i>=0; i--){
        revstr = revstr+ str[i];
    }
    return revstr;
}
alert(reverseString("Hello World!"));

3. Verwenden der for-of-Schleife

function reverseString(str){
    let strn ="";
    for(let char of str){
        strn = char + strn;
    }
    return strn;
}
alert(reverseString("Get well soon"));

4. Verwenden der forEach / Array-Methode höherer Ordnung:

function reverseString(str){

  let revSrring = "";
  str.split("").forEach(function(char){
    
    revSrring = char + revSrring;
  
  });
  return revSrring;
}
alert(reverseString("Learning JavaScript"));

5. ES6-Standard:

function reverseString(str){

  let revSrring = "";
  str.split("").forEach(char => revSrring = char + revSrring);
  return revSrring;
}
alert(reverseString("Learning JavaScript"));

6. Der neueste Weg:

function reverseString(str){

  return str.split("").reduce(function(revString, char){
       return char + revString;
  }, "");
 
}

alert(reverseString("Learning JavaScript"));

7. Sie können das Ergebnis auch wie folgt erhalten:

function reverseString(str){

  return str.split("").reduce((revString, char)=> char + revString, "");
 
}
alert(reverseString("Learning JavaScript"));


7

In ES6 haben Sie noch eine Option

function reverseString (str) {
  return [...str].reverse().join('')
}

reverseString('Hello');

6

Dies ist der einfachste Weg, den ich denke

var reverse = function(str) {
    var arr = [];
    
    for (var i = 0, len = str.length; i <= len; i++) {
        arr.push(str.charAt(len - i))
    }

    return arr.join('');
}

console.log(reverse('I want a 🍺'));


3
Es ist schön, dass Sie ein Emoji in Ihr Beispiel aufgenommen haben. Damit wir schnell sehen, dass dies bei Emojis und vielen anderen Unicode-Zeichen eindeutig nicht funktioniert.
Mhor Mé

Glaube, obwohl Ihre Antwort richtig ist, stimme ich nicht zu, dass dies der einfachste Weg ist. Die ersten Antworten nutzen Array.prototype.reverse()dies am einfachsten, daher die beliebteste Antwort. Natürlich würde es gute Vorkenntnisse in JavaScript erfordern.
Daniel

6
var str = 'sample string';
[].map.call(str, function(x) {
  return x;
}).reverse().join('');

ODER

var str = 'sample string';
console.log(str.split('').reverse().join(''));

// Ausgabe: 'gnirts elpmas'


Ihr gesamter 'Map'-Teil kann als geschrieben werden [...str].

5

Ich weiß, dass dies eine alte Frage ist, die gut beantwortet wurde, aber zu meiner eigenen Unterhaltung habe ich die folgende Umkehrfunktion geschrieben und dachte, ich würde sie teilen, falls sie für andere nützlich wäre. Es behandelt sowohl Ersatzpaare als auch Kombinationsmarken:

function StringReverse (str)
{
  var charArray = [];
  for (var i = 0; i < str.length; i++)
    {
      if (i+1 < str.length)
        {
          var value = str.charCodeAt(i);
          var nextValue = str.charCodeAt(i+1);
          if (   (   value >= 0xD800 && value <= 0xDBFF
                  && (nextValue & 0xFC00) == 0xDC00) // Surrogate pair)
              || (nextValue >= 0x0300 && nextValue <= 0x036F)) // Combining marks
            {
              charArray.unshift(str.substring(i, i+2));
              i++; // Skip the other half
              continue;
            }
        }

      // Otherwise we just have a rogue surrogate marker or a plain old character.
      charArray.unshift(str[i]);
    }

  return charArray.join('');
}

Alle Requisiten an Mathias, Punycode und verschiedene andere Referenzen, um mich über die Komplexität der Zeichenkodierung in JavaScript zu unterrichten.



3

Wenn Sie keine eingebaute Funktion verwenden möchten. Versuche dies

var string = 'abcdefg';
var newstring = '';

for(let i = 0; i < string.length; i++){
    newstring = string[i] += newstring;
}

console.log(newstring);

2

Die eigentliche Antwort lautet: Sie können es nicht an Ort und Stelle umkehren, aber Sie können eine neue Zeichenfolge erstellen, die umgekehrt ist.

Nur als Übung, um mit Rekursion zu spielen: Manchmal, wenn Sie zu einem Interview gehen, fragt Sie der Interviewer, wie Sie dies mit Rekursion tun sollen, und ich denke, die "bevorzugte Antwort" könnte lauten: "Ich würde dies lieber nicht in Rekursion tun, wie es ist." kann leicht einen Stapelüberlauf verursachen "(weil dies O(n)nicht der Fall ist O(log n). Wenn dies O(log n)der Fall ist , ist es ziemlich schwierig, einen Stapelüberlauf zu erhalten - 4 Milliarden Elemente könnten von einer Stapelstufe von 32 verarbeitet werden, da 2 ** 32 4294967296 ist. Aber wenn es so istO(n) Fall , kann es leicht zu einem Stapelüberlauf kommen.

Manchmal fragt Sie der Interviewer immer noch: "Nur als Übung, warum schreiben Sie sie nicht immer noch mit Rekursion?" Und hier ist es:

String.prototype.reverse = function() {
    if (this.length <= 1) return this;
    else return this.slice(1).reverse() + this.slice(0,1);
}

Testlauf:

var s = "";
for(var i = 0; i < 1000; i++) {
    s += ("apple" + i);
}
console.log(s.reverse());

Ausgabe:

999elppa899elppa...2elppa1elppa0elppa

Um zu versuchen , einen Stapelüberlauf immer, ich geändert , 1000um 10000in Google Chrome, und berichtete:

RangeError: Maximum call stack size exceeded

2

Zeichenfolgen selbst sind unveränderlich, aber Sie können problemlos eine umgekehrte Kopie mit dem folgenden Code erstellen:

function reverseString(str) {

  var strArray = str.split("");
  strArray.reverse();

  var strReverse = strArray.join("");

  return strReverse;
}

reverseString("hello");

2
//es6
//array.from
const reverseString = (string) => Array.from(string).reduce((a, e) => e + a);
//split
const reverseString = (string) => string.split('').reduce((a, e) => e + a); 

//split problem
"𠜎𠺢".split('')[0] === Array.from("𠜎𠺢")[0] // "�" === "𠜎" => false
"😂😹🤗".split('')[0] === Array.from("😂😹🤗")[0] // "�" === "😂" => false

1
Dies hat den Vorteil, dass zusätzliche Ebenenzeichen korrekt behandelt werden.

2

Eine kleine Funktion, die sowohl diakritische Zeichen als auch 2-Byte-Zeichen kombiniert:

(function(){
  var isCombiningDiacritic = function( code )
  {
    return (0x0300 <= code && code <= 0x036F)  // Comb. Diacritical Marks
        || (0x1AB0 <= code && code <= 0x1AFF)  // Comb. Diacritical Marks Extended
        || (0x1DC0 <= code && code <= 0x1DFF)  // Comb. Diacritical Marks Supplement
        || (0x20D0 <= code && code <= 0x20FF)  // Comb. Diacritical Marks for Symbols
        || (0xFE20 <= code && code <= 0xFE2F); // Comb. Half Marks

  };

  String.prototype.reverse = function()
  {
    var output = "",
        i      = this.length - 1,
        width;

    for ( ; i >= 0; --i )
    {
      width = 1;
      while( i > 0 && isCombiningDiacritic( this.charCodeAt(i) ) )
      {
        --i;
        width++;
      }

      if (
           i > 0
        && "\uDC00" <= this[i]   && this[i]   <= "\uDFFF"
        && "\uD800" <= this[i-1] && this[i-1] <= "\uDBFF"
      )
      {
        --i;
        width++;
      }

      output += this.substr( i, width );
    }

    return output;
  }
})();

// Tests
[
  'abcdefg',
  'ab\u0303c',
  'a\uD83C\uDFA5b',
  'a\uD83C\uDFA5b\uD83C\uDFA6c',
  'a\uD83C\uDFA5b\u0306c\uD83C\uDFA6d',
  'TO͇̹̺ͅƝ̴ȳ̳ TH̘Ë͖́̉ ͠P̯͍̭O̚​N̐Y̡' // copied from http://stackoverflow.com/a/1732454/1509264
].forEach(
  function(str){ console.log( str + " -> " + str.reverse() ); }
);
  


Aktualisieren

Eine vollständigere Liste der Kombination von Diakritika lautet:

      var isCombiningDiacritic = function( code )
      {
        return (0x0300 <= code && code <= 0x036F)
            || (0x0483 <= code && code <= 0x0489)
            || (0x0591 <= code && code <= 0x05BD)
            || (code == 0x05BF)
            || (0x05C1 <= code && code <= 0x05C2)
            || (0x05C4 <= code && code <= 0x05C5)
            || (code == 0x05C7)
            || (0x0610 <= code && code <= 0x061A)
            || (0x064B <= code && code <= 0x065F)
            || (code == 0x0670)
            || (0x06D6 <= code && code <= 0x06DC)
            || (0x06DF <= code && code <= 0x06E4)
            || (0x06E7 <= code && code <= 0x06E8)
            || (0x06EA <= code && code <= 0x06ED)
            || (code == 0x0711)
            || (0x0730 <= code && code <= 0x074A)
            || (0x07A6 <= code && code <= 0x07B0)
            || (0x07EB <= code && code <= 0x07F3)
            || (code == 0x07FD)
            || (0x0816 <= code && code <= 0x0819)
            || (0x081B <= code && code <= 0x0823)
            || (0x0825 <= code && code <= 0x0827)
            || (0x0829 <= code && code <= 0x082D)
            || (0x0859 <= code && code <= 0x085B)
            || (0x08D3 <= code && code <= 0x08E1)
            || (0x08E3 <= code && code <= 0x0902)
            || (code == 0x093A)
            || (code == 0x093C)
            || (0x0941 <= code && code <= 0x0948)
            || (code == 0x094D)
            || (0x0951 <= code && code <= 0x0957)
            || (0x0962 <= code && code <= 0x0963)
            || (code == 0x0981)
            || (code == 0x09BC)
            || (0x09C1 <= code && code <= 0x09C4)
            || (code == 0x09CD)
            || (0x09E2 <= code && code <= 0x09E3)
            || (0x09FE <= code && code <= 0x0A02)
            || (code == 0x0A3C)
            || (0x0A41 <= code && code <= 0x0A51)
            || (0x0A70 <= code && code <= 0x0A71)
            || (code == 0x0A75)
            || (0x0A81 <= code && code <= 0x0A82)
            || (code == 0x0ABC)
            || (0x0AC1 <= code && code <= 0x0AC8)
            || (code == 0x0ACD)
            || (0x0AE2 <= code && code <= 0x0AE3)
            || (0x0AFA <= code && code <= 0x0B01)
            || (code == 0x0B3C)
            || (code == 0x0B3F)
            || (0x0B41 <= code && code <= 0x0B44)
            || (0x0B4D <= code && code <= 0x0B56)
            || (0x0B62 <= code && code <= 0x0B63)
            || (code == 0x0B82)
            || (code == 0x0BC0)
            || (code == 0x0BCD)
            || (code == 0x0C00)
            || (code == 0x0C04)
            || (0x0C3E <= code && code <= 0x0C40)
            || (0x0C46 <= code && code <= 0x0C56)
            || (0x0C62 <= code && code <= 0x0C63)
            || (code == 0x0C81)
            || (code == 0x0CBC)
            || (0x0CCC <= code && code <= 0x0CCD)
            || (0x0CE2 <= code && code <= 0x0CE3)
            || (0x0D00 <= code && code <= 0x0D01)
            || (0x0D3B <= code && code <= 0x0D3C)
            || (0x0D41 <= code && code <= 0x0D44)
            || (code == 0x0D4D)
            || (0x0D62 <= code && code <= 0x0D63)
            || (code == 0x0DCA)
            || (0x0DD2 <= code && code <= 0x0DD6)
            || (code == 0x0E31)
            || (0x0E34 <= code && code <= 0x0E3A)
            || (0x0E47 <= code && code <= 0x0E4E)
            || (code == 0x0EB1)
            || (0x0EB4 <= code && code <= 0x0EBC)
            || (0x0EC8 <= code && code <= 0x0ECD)
            || (0x0F18 <= code && code <= 0x0F19)
            || (code == 0x0F35)
            || (code == 0x0F37)
            || (code == 0x0F39)
            || (0x0F71 <= code && code <= 0x0F7E)
            || (0x0F80 <= code && code <= 0x0F84)
            || (0x0F86 <= code && code <= 0x0F87)
            || (0x0F8D <= code && code <= 0x0FBC)
            || (code == 0x0FC6)
            || (0x102D <= code && code <= 0x1030)
            || (0x1032 <= code && code <= 0x1037)
            || (0x1039 <= code && code <= 0x103A)
            || (0x103D <= code && code <= 0x103E)
            || (0x1058 <= code && code <= 0x1059)
            || (0x105E <= code && code <= 0x1060)
            || (0x1071 <= code && code <= 0x1074)
            || (code == 0x1082)
            || (0x1085 <= code && code <= 0x1086)
            || (code == 0x108D)
            || (code == 0x109D)
            || (0x135D <= code && code <= 0x135F)
            || (0x1712 <= code && code <= 0x1714)
            || (0x1732 <= code && code <= 0x1734)
            || (0x1752 <= code && code <= 0x1753)
            || (0x1772 <= code && code <= 0x1773)
            || (0x17B4 <= code && code <= 0x17B5)
            || (0x17B7 <= code && code <= 0x17BD)
            || (code == 0x17C6)
            || (0x17C9 <= code && code <= 0x17D3)
            || (code == 0x17DD)
            || (0x180B <= code && code <= 0x180D)
            || (0x1885 <= code && code <= 0x1886)
            || (code == 0x18A9)
            || (0x1920 <= code && code <= 0x1922)
            || (0x1927 <= code && code <= 0x1928)
            || (code == 0x1932)
            || (0x1939 <= code && code <= 0x193B)
            || (0x1A17 <= code && code <= 0x1A18)
            || (code == 0x1A1B)
            || (code == 0x1A56)
            || (0x1A58 <= code && code <= 0x1A60)
            || (code == 0x1A62)
            || (0x1A65 <= code && code <= 0x1A6C)
            || (0x1A73 <= code && code <= 0x1A7F)
            || (0x1AB0 <= code && code <= 0x1B03)
            || (code == 0x1B34)
            || (0x1B36 <= code && code <= 0x1B3A)
            || (code == 0x1B3C)
            || (code == 0x1B42)
            || (0x1B6B <= code && code <= 0x1B73)
            || (0x1B80 <= code && code <= 0x1B81)
            || (0x1BA2 <= code && code <= 0x1BA5)
            || (0x1BA8 <= code && code <= 0x1BA9)
            || (0x1BAB <= code && code <= 0x1BAD)
            || (code == 0x1BE6)
            || (0x1BE8 <= code && code <= 0x1BE9)
            || (code == 0x1BED)
            || (0x1BEF <= code && code <= 0x1BF1)
            || (0x1C2C <= code && code <= 0x1C33)
            || (0x1C36 <= code && code <= 0x1C37)
            || (0x1CD0 <= code && code <= 0x1CD2)
            || (0x1CD4 <= code && code <= 0x1CE0)
            || (0x1CE2 <= code && code <= 0x1CE8)
            || (code == 0x1CED)
            || (code == 0x1CF4)
            || (0x1CF8 <= code && code <= 0x1CF9)
            || (0x1DC0 <= code && code <= 0x1DFF)
            || (0x20D0 <= code && code <= 0x20F0)
            || (0x2CEF <= code && code <= 0x2CF1)
            || (code == 0x2D7F)
            || (0x2DE0 <= code && code <= 0x2DFF)
            || (0x302A <= code && code <= 0x302D)
            || (0x3099 <= code && code <= 0x309A)
            || (0xA66F <= code && code <= 0xA672)
            || (0xA674 <= code && code <= 0xA67D)
            || (0xA69E <= code && code <= 0xA69F)
            || (0xA6F0 <= code && code <= 0xA6F1)
            || (code == 0xA802)
            || (code == 0xA806)
            || (code == 0xA80B)
            || (0xA825 <= code && code <= 0xA826)
            || (0xA8C4 <= code && code <= 0xA8C5)
            || (0xA8E0 <= code && code <= 0xA8F1)
            || (code == 0xA8FF)
            || (0xA926 <= code && code <= 0xA92D)
            || (0xA947 <= code && code <= 0xA951)
            || (0xA980 <= code && code <= 0xA982)
            || (code == 0xA9B3)
            || (0xA9B6 <= code && code <= 0xA9B9)
            || (0xA9BC <= code && code <= 0xA9BD)
            || (code == 0xA9E5)
            || (0xAA29 <= code && code <= 0xAA2E)
            || (0xAA31 <= code && code <= 0xAA32)
            || (0xAA35 <= code && code <= 0xAA36)
            || (code == 0xAA43)
            || (code == 0xAA4C)
            || (code == 0xAA7C)
            || (code == 0xAAB0)
            || (0xAAB2 <= code && code <= 0xAAB4)
            || (0xAAB7 <= code && code <= 0xAAB8)
            || (0xAABE <= code && code <= 0xAABF)
            || (code == 0xAAC1)
            || (0xAAEC <= code && code <= 0xAAED)
            || (code == 0xAAF6)
            || (code == 0xABE5)
            || (code == 0xABE8)
            || (code == 0xABED)
            || (code == 0xFB1E)
            || (0xFE00 <= code && code <= 0xFE0F)
            || (0xFE20 <= code && code <= 0xFE2F)
            || (code == 0x101FD)
            || (code == 0x102E0)
            || (0x10376 <= code && code <= 0x1037A)
            || (0x10A01 <= code && code <= 0x10A0F)
            || (0x10A38 <= code && code <= 0x10A3F)
            || (0x10AE5 <= code && code <= 0x10AE6)
            || (0x10D24 <= code && code <= 0x10D27)
            || (0x10F46 <= code && code <= 0x10F50)
            || (code == 0x11001)
            || (0x11038 <= code && code <= 0x11046)
            || (0x1107F <= code && code <= 0x11081)
            || (0x110B3 <= code && code <= 0x110B6)
            || (0x110B9 <= code && code <= 0x110BA)
            || (0x11100 <= code && code <= 0x11102)
            || (0x11127 <= code && code <= 0x1112B)
            || (0x1112D <= code && code <= 0x11134)
            || (code == 0x11173)
            || (0x11180 <= code && code <= 0x11181)
            || (0x111B6 <= code && code <= 0x111BE)
            || (0x111C9 <= code && code <= 0x111CC)
            || (0x1122F <= code && code <= 0x11231)
            || (code == 0x11234)
            || (0x11236 <= code && code <= 0x11237)
            || (code == 0x1123E)
            || (code == 0x112DF)
            || (0x112E3 <= code && code <= 0x112EA)
            || (0x11300 <= code && code <= 0x11301)
            || (0x1133B <= code && code <= 0x1133C)
            || (code == 0x11340)
            || (0x11366 <= code && code <= 0x11374)
            || (0x11438 <= code && code <= 0x1143F)
            || (0x11442 <= code && code <= 0x11444)
            || (code == 0x11446)
            || (code == 0x1145E)
            || (0x114B3 <= code && code <= 0x114B8)
            || (code == 0x114BA)
            || (0x114BF <= code && code <= 0x114C0)
            || (0x114C2 <= code && code <= 0x114C3)
            || (0x115B2 <= code && code <= 0x115B5)
            || (0x115BC <= code && code <= 0x115BD)
            || (0x115BF <= code && code <= 0x115C0)
            || (0x115DC <= code && code <= 0x115DD)
            || (0x11633 <= code && code <= 0x1163A)
            || (code == 0x1163D)
            || (0x1163F <= code && code <= 0x11640)
            || (code == 0x116AB)
            || (code == 0x116AD)
            || (0x116B0 <= code && code <= 0x116B5)
            || (code == 0x116B7)
            || (0x1171D <= code && code <= 0x1171F)
            || (0x11722 <= code && code <= 0x11725)
            || (0x11727 <= code && code <= 0x1172B)
            || (0x1182F <= code && code <= 0x11837)
            || (0x11839 <= code && code <= 0x1183A)
            || (0x119D4 <= code && code <= 0x119DB)
            || (code == 0x119E0)
            || (0x11A01 <= code && code <= 0x11A06)
            || (0x11A09 <= code && code <= 0x11A0A)
            || (0x11A33 <= code && code <= 0x11A38)
            || (0x11A3B <= code && code <= 0x11A3E)
            || (code == 0x11A47)
            || (0x11A51 <= code && code <= 0x11A56)
            || (0x11A59 <= code && code <= 0x11A5B)
            || (0x11A8A <= code && code <= 0x11A96)
            || (0x11A98 <= code && code <= 0x11A99)
            || (0x11C30 <= code && code <= 0x11C3D)
            || (0x11C92 <= code && code <= 0x11CA7)
            || (0x11CAA <= code && code <= 0x11CB0)
            || (0x11CB2 <= code && code <= 0x11CB3)
            || (0x11CB5 <= code && code <= 0x11CB6)
            || (0x11D31 <= code && code <= 0x11D45)
            || (code == 0x11D47)
            || (0x11D90 <= code && code <= 0x11D91)
            || (code == 0x11D95)
            || (code == 0x11D97)
            || (0x11EF3 <= code && code <= 0x11EF4)
            || (0x16AF0 <= code && code <= 0x16AF4)
            || (0x16B30 <= code && code <= 0x16B36)
            || (code == 0x16F4F)
            || (0x16F8F <= code && code <= 0x16F92)
            || (0x1BC9D <= code && code <= 0x1BC9E)
            || (0x1D167 <= code && code <= 0x1D169)
            || (0x1D17B <= code && code <= 0x1D182)
            || (0x1D185 <= code && code <= 0x1D18B)
            || (0x1D1AA <= code && code <= 0x1D1AD)
            || (0x1D242 <= code && code <= 0x1D244)
            || (0x1DA00 <= code && code <= 0x1DA36)
            || (0x1DA3B <= code && code <= 0x1DA6C)
            || (code == 0x1DA75)
            || (code == 0x1DA84)
            || (0x1DA9B <= code && code <= 0x1E02A)
            || (0x1E130 <= code && code <= 0x1E136)
            || (0x1E2EC <= code && code <= 0x1E2EF)
            || (0x1E8D0 <= code && code <= 0x1E8D6)
            || (0x1E944 <= code && code <= 0x1E94A)
            || (0xE0100 <= code && code <= 0xE01EF);
      };

Ein würdiger Versuch, aber wenn Sie die Datei UnicodeData.txt scannen würden, würden Sie feststellen, dass es 316 solcher Bereiche zum Kombinieren von Diakritika gibt, anstatt 5.
Mr Lister

@MrLister Die Lösung besteht dann darin, die isCombiningDiacriticFunktion so zu bearbeiten , dass sie alle 316 Bereiche enthält. Fühlen Sie sich frei, diese Bearbeitung bereitzustellen, da Sie anscheinend die Daten zur Hand haben.
MT0

1
function reverseString(string) {
    var reversedString = "";
    var stringLength = string.length - 1;
    for (var i = stringLength; i >= 0; i--) {
        reversedString += string[i];
    }
    return reversedString;
}

1

ohne String in Array umzuwandeln;

String.prototype.reverse = function() {

    var ret = "";
    var size = 0;

    for (var i = this.length - 1; -1 < i; i -= size) {

        if (
          '\uD800' <= this[i - 1] && this[i - 1] <= '\uDBFF' && 
          '\uDC00' <= this[i]     && this[i]     <= '\uDFFF'
        ) {
            size = 2;
            ret += this[i - 1] + this[i];
        } else {
            size = 1;
            ret += this[i];
        }
    }

    return ret;
}

console.log('anãnam anañam' === 'mañana mañana'.reverse());

Verwenden von Array.reverse ohne Konvertieren von Zeichen in Codepunkte;

String.prototype.reverse = function() {

    var array = this.split("").reverse();

    for (var i = 0; i < this.length; ++i) {

        if (
          '\uD800' <= this[i - 1] && this[i - 1] <= '\uDBFF' && 
          '\uDC00' <= this[i]     && this[i]     <= '\uDFFF'
        ) {
            array[i - 1] = array[i - 1] + array[i];
            array[i] = array[i - 1].substr(0, 1);
            array[i - 1] = array[i - 1].substr(1, 1);
        }

    }

    return array.join("");
}

console.log('anãnam anañam' === 'mañana mañana'.reverse());

Für die zweite Version: var c = array[i-1]; array[i-1] = array[i]; array[i] = c;erfordert keine Verkettung des Codepaars. Außerdem sollte die for-Schleife am 1.
MT0

Die zweite Version funktioniert nicht mit '\ud83c\ud83c\udfa5'.reverse()- sie gibt dieselbe Ausgabe aus wie die Eingabe. Das Hinzufügen ++i;innerhalb der ifAnweisung sollte dies beheben.
MT0

Bei zweiten Gedanken - dies behandelt nicht das Kombinieren von Diakritika: 'a\u0303bc'.reverse() === 'cba\u0303'sollte true zurückgeben.
MT0

1

Ich denke, String.prototype.reverse ist ein guter Weg, um dieses Problem zu lösen. der Code wie folgt;

String.prototype.reverse = function() {
  return this.split('').reverse().join('');
}

var str = 'this is a good example for string reverse';
str.reverse();
-> "esrever gnirts rof elpmaxe doog a si siht";

1

Verwenden von Array-Funktionen,

String.prototype.reverse = function(){
    return [].reduceRight.call(this, function(last, secLast){return last + secLast});
}

1
var str = "my name is saurabh ";
var empStr='',finalString='';
var chunk=[];
function reverse(str){
var i,j=0,n=str.length;
    for(i=0;i<n;++i){
        if(str[i]===' '){
            chunk[j]=empStr;
            empStr = '';
            j++;
        }else{
            empStr=empStr+str[i];
        }
    }
    for(var z=chunk.length-1;z>=0;z--){
        finalString = finalString +' '+ chunk[z];
        console.log(finalString);
    }
    return true;
}
reverse(str);

Wie ist das "an Ort und Stelle"?
Sudhansu Choudhary

1

Mein eigener ursprünglicher Versuch ...

var str = "The Car";

function reverseStr(str) {
  var reversed = "";
  var len = str.length;
  for (var i = 1; i < (len + 1); i++) {  
    reversed += str[len - i];      
  }

  return reversed;
}

var strReverse = reverseStr(str);    
console.log(strReverse);
// "raC ehT"

http://jsbin.com/bujiwo/19/edit?js,console,output


1

Halten Sie es trocken und einfach albern!

function reverse(s){
let str = s;
var reverse = '';
for (var i=str.length;i>0;i--){

    var newstr = str.substring(0,i)
    reverse += newstr.substr(-1,1)
}
return reverse;
}

1

OK, ziemlich einfach, Sie können eine Funktion mit einer einfachen Schleife erstellen, um die Zeichenfolge für Sie umzukehren, ohne zu verwenden reverse().charAt() etc wie folgt aus :

Zum Beispiel haben Sie diese Zeichenfolge:

var name = "StackOverflow";

Erstellen Sie eine Funktion wie diese, ich nenne es reverseString...

function reverseString(str) {
  if(!str.trim() || 'string' !== typeof str) {
    return;
  }
  let l=str.length, s='';
  while(l > 0) {
    l--;
    s+= str[l];
  }
  return s;
}

Und Sie können es so nennen:

reverseString(name);

Und das Ergebnis wird sein:

"wolfrevOkcatS"

1

Beste Möglichkeiten, eine Zeichenfolge in JavaScript umzukehren

1) Array.reverse:

Sie denken wahrscheinlich, warten Sie, ich dachte, wir kehren eine Zeichenfolge um. Warum verwenden Sie die Array.reverse-Methode? Mit der String.split-Methode konvertieren wir unseren String in ein Array von Zeichen. Dann kehren wir die Reihenfolge jedes Werts im Array um und konvertieren das Array schließlich mit der Methode Array.join zurück in einen String.

function reverseString(str) {
    return str.split('').reverse().join('');
}
reverseString('dwayne');

2) Dekrementieren der while-Schleife:

Obwohl diese Lösung ziemlich ausführlich ist, hat sie ihre Vorteile gegenüber der ersten Lösung. Sie erstellen kein Array und verketten lediglich eine Zeichenfolge basierend auf Zeichen aus der Quellzeichenfolge.

Aus Sicht der Leistung würde dieser wahrscheinlich die besten Ergebnisse liefern (obwohl nicht getestet). Bei extrem langen Saiten können die Leistungssteigerungen jedoch aus dem Fenster fallen.

function reverseString(str) {
    var temp = '';
    var i = str.length;

    while (i > 0) {
        temp += str.substring(i - 1, i);
        i--;
    }


    return temp;
}
reverseString('dwayne');

3) Rekursion

Ich finde es toll, wie einfach und klar diese Lösung ist. Sie können deutlich sehen, dass die Methoden String.charAt und String.substr verwendet werden, um einen anderen Wert zu durchlaufen, indem Sie sich jedes Mal selbst aufrufen, bis der String leer ist, von dem der Ternär nur einen leeren String zurückgibt, anstatt die Rekursion zu verwenden, um sich selbst aufzurufen . Dies würde wahrscheinlich die zweitbeste Leistung nach der zweiten Lösung ergeben.

function reverseString(str) {
    return (str === '') ? '' : reverseString(str.substr(1)) + str.charAt(0);
}
reverseString('dwayne');
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.