Come si inverte una stringa in atto in JavaScript?


435

Come invertire una stringa sul posto (o sul posto) in JavaScript quando viene passata a una funzione con un'istruzione return, senza usare le funzioni integrate ( .reverse(), .charAt()ecc.)?


quindi, non ti è permesso usare .charAt () per ottenere i caratteri della stringa?
Irwin,

155
Non puoi. Le stringhe JavaScript sono immutabili, il che significa che la memoria allocata a ciascuna non può essere scritta, rendendo impossibili le inversioni "sul posto".
Crescent Fresh,

2
Re: crescentfresh commento Vedere stackoverflow.com/questions/51185/...
baudtack

1
@crescentfresh dovresti pubblicarlo come una nuova risposta.
baudtack,

Risposte:


737

Finché hai a che fare con semplici caratteri ASCII e sei felice di usare le funzioni integrate, funzionerà:

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

Se hai bisogno di una soluzione che supporti UTF-16 o altri caratteri multi-byte, tieni presente che questa funzione fornirà stringhe unicode non valide o stringhe valide che sembrano divertenti. Potresti invece considerare questa risposta .

[... s] è a conoscenza di Unicode, una piccola modifica fornisce: -

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

44
Questo è rotto per le stringhe UTF-16 che contengono coppie surrogate, ovvero caratteri al di fuori del piano multilingue di base. Fornirà anche risultati divertenti per le stringhe contenenti combinazioni di caratteri, ad esempio una diaeresi potrebbe apparire sul carattere seguente. Il primo numero porterà a stringhe unicode non valide, il secondo a stringhe valide che sembrano divertenti.
Martin Probst,

2
@Richeve Bebedor "Tutto senza utilizzare le funzioni integrate? .Reverse ()" Questa non sarebbe una soluzione accettata poiché non rientra nei confini della domanda, nonostante sia una soluzione praticabile per invertire una stringa in JS.
David Starkey,

1
@DavidStarkey: Sì, guardando indietro a questo quasi quattro anni dopo, è difficile vedere come ho perso così tanto il punto della domanda. Sembra che avrei dovuto aspettare solo due minuti e ho votato a favore di crescentfresh sul post originale!
belacqua,

14
@MartinProbst La mia risposta fornisce una soluzione Unicode-aware al problema che si occupa di coppie di surrogati e marchi, che conciliano correttamente: stackoverflow.com/a/16776380/96656
Mathias Bynens

1
Per UTF-16 return [...s].reverse().join("");potrebbe funzionare.
user4642212

411

La seguente tecnica (o simile) viene comunemente utilizzata per invertire una stringa in JavaScript:

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

In effetti, tutte le risposte postate finora sono una variazione di questo modello. Tuttavia, ci sono alcuni problemi con questa soluzione. Per esempio:

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

Se ti stai chiedendo perché questo accada, leggi la codifica dei caratteri interna di JavaScript . (TL; DR: 𝌆è un simbolo astrale e JavaScript lo espone come due unità di codice separate.)

Ma c'è di più:

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

Una buona stringa per testare le implementazioni inverse della stringa è la seguente :

'foo 𝌆 bar mañana mañana'

Perché? Perché contiene un simbolo astrale ( 𝌆) (che sono rappresentati da coppie surrogate in JavaScript ) e un segno di combinazione ( l'ultimo in mañanarealtà consiste di due simboli: U + 006E LATINA PICCOLA LATINA N e U + 0303 COMBINING TILDE).

L'ordine in cui appaiono le coppie surrogate non può essere invertito, altrimenti il ​​simbolo astrale non comparirà più nella stringa "invertita". Ecco perché hai visto quei ��segni nell'output dell'esempio precedente.

I segni combinati vengono sempre applicati al simbolo precedente, quindi devi considerare sia il simbolo principale (U + 006E LATINA PICCOLA LETTERA N) come il segno combinato (U + 0303 COMBINING TILDE) nel suo insieme. L'inversione del loro ordine comporterà l'abbinamento del segno di combinazione con un altro simbolo nella stringa. Ecco perché l'output di esempio ha avuto invece di ñ.

Speriamo che questo spieghi perché tutte le risposte postate finora sono sbagliate .


Per rispondere alla tua domanda iniziale - come invertire [correttamente] una stringa in JavaScript -, ho scritto una piccola libreria JavaScript che è in grado di invertire la stringa compatibile con Unicode. Non ha nessuno dei problemi che ho appena menzionato. La biblioteca si chiama Esrever ; il suo codice è su GitHub e funziona praticamente in qualsiasi ambiente JavaScript. Viene fornito con un'utilità di shell / binario, quindi puoi facilmente invertire le stringhe dal tuo terminale, se lo desideri.

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

Per quanto riguarda la parte "sul posto", vedere le altre risposte.


65
Dovresti includere la parte principale del codice di Esrever nella tua risposta.
r0estir0bbe,

1
@Meglio Con quell'approccio specifico, sì.
Mathias Bynens,

8
Il problema, fuori rotta, è che "invertire una stringa" sembra inequivocabile, ma non è di fronte ai problemi menzionati qui. L'inversione di una stringa restituisce la stringa che una volta stampata visualizzerebbe i cluster di grafema nella stringa in ordine inverso? Da un lato, sembra probabile. Dall'altro, perché mai vorresti farlo? Questa definizione dipende dalla sua stampa e la stampa di una stringa invertita è raramente utile. Come parte di un algoritmo, le tue esigenze potrebbero essere completamente diverse.
Martijn,

19
Mentre questo fa un ottimo lavoro nel spiegare il problema, la risposta effettiva è in un altro castello . Come ha detto @ r0estir0bbe oltre un anno fa, il codice pertinente dovrebbe essere nella risposta, non solo collegato.
TJ Crowder,

4
"Speriamo che questo spieghi perché tutte le risposte postate finora sono sbagliate" - Questa affermazione è troppo forte. Molti casi d'uso non richiedono il supporto UTF-16 (semplice esempio; utilizzo di componenti e parametri URL e URL). Una soluzione non è "sbagliata" semplicemente perché non gestisce uno scenario non necessario. In particolare, la risposta più votata dichiara esplicitamente che funziona solo con caratteri ASCII e quindi sicuramente non è nemmeno un po 'sbagliata.
aroth

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

o

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

Sono assolutamente d'accordo con il prototipo String.
Jeff Meatball Yang,

3
la concatenazione di stringhe è costosa. Meglio costruire un array e unirlo o usare concat ().
Bjorn,

2
Il numero 1 è il migliore, il numero 2 potrebbe essere terribilmente lento
adamJev

9
Tuttavia, nessuna soluzione funziona quando sono presenti caratteri composti Unicode.
Eric Grange,

2
@JuanMendes Ho lasciato quel commento nel 2009, le cose sono cambiate negli ultimi 4 anni. : P
Bjorn,

63

Analisi dettagliate e dieci modi diversi per invertire una stringa e i relativi dettagli di prestazione.

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

Prestazioni di queste implementazioni:

Implementazione (i) più performante per browser

  • Chrome 15: implementazioni 1 e 6
  • Firefox 7 - Implementazione 6
  • IE 9 - Implementazione 4
  • Opera 12 - Implementazione 9

Ecco quelle implementazioni:

Implementazione 1:

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

Implementazione 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('');
}

Implementazione 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('');
}

Implementazione 4:

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

Implementazione 5:

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

Implementazione 6:

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

Implementazione 7:

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

Implementazione 8:

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

Implementazione 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('');
    }

Implementazione 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

L'intero "invertire una stringa sul posto" è una domanda di intervista antiquata programmatori C, e le persone che sono state intervistate da loro (per vendetta, forse?), Chiederanno. Sfortunatamente, è la parte "Sul posto" che non funziona più perché le stringhe in quasi tutti i linguaggi gestiti (JS, C #, ecc.) Usano stringhe immutabili, sconfiggendo così l'idea di spostare una stringa senza allocare nuova memoria.

Mentre le soluzioni sopra invertono effettivamente una stringa, non lo fanno senza allocare più memoria e quindi non soddisfano le condizioni. È necessario avere accesso diretto alla stringa come allocata ed essere in grado di manipolare la sua posizione di memoria originale per poterlo invertire.

Personalmente odio davvero questo tipo di domande di intervista, ma purtroppo sono sicuro che continueremo a vederle per gli anni a venire.


7
Posso almeno dire che un po 'di tempo fa un intervistatore è rimasto piuttosto colpito quando mi ha chiesto come invertire una stringa "sul posto" in JS e ho spiegato perché è impossibile poiché le stringhe in JS sono immutabili. Non so se fosse la risposta che si aspettava o se l'ho educato un po '. Ad ogni modo ha funzionato bene;)
Chev

1
Forse intende "gestito" da un garbage collector, almeno questo è ciò che di solito si intende per "linguaggio gestito" o la presenza di una macchina virtuale / ambiente di runtime virtuale? @torazaburo
AntonB,

39

Innanzitutto, utilizzare Array.from()per trasformare una stringa in un array, quindi Array.prototype.reverse()per invertire l'array e quindi Array.prototype.join()per ripristinarlo.

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

Ha un sovraccarico, ma questa è una soluzione elegante! Non è possibile riscrivere la reverselogica preesistente .
Gershom,

2
@felixfbecker No, string.split('')non funziona. Vedi questa risposta per ulteriori spiegazioni.
Michał Perłakowski,

5
Questa dovrebbe essere la risposta accettata perché funziona anche con Unicode. Ad esempio, dall'esempio sopra:Array.from('foo 𝌆 bar mañana mañana').reverse().join('') == 'anãnam anañam rab 𝌆 oof'
Julian TF

3
@JulianTF Non esattamente, una tilde viene comunque applicata a 'a' invece di 'n'.
Roman Boiko,

2
@RomanBoiko Vero, ma puoi prima normalizzare la stringa. Array.from('foo 𝌆 bar mañana mañana'.normalize('NFC')).reverse().join('')diventerà"anañam anañam rab 𝌆 oof"
Lister

26

In ECMAScript 6, puoi invertire una stringa ancora più velocemente senza utilizzare il .split('')metodo split, con l' operatore spread in questo modo:

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

1
ES6 ti consente anche di usare due backtick `` invece di('')

non c'è motivo di usare due backtick in questo caso
Vic

1
A meno che tu non stia giocando a golf, dovresti evitarlo. La scrittura string.split('')è più chiara per la maggior parte delle persone rispetto a [...string].
AnnanFay,

1
@AnnanFay .split('')ha il problema con i caratteri dei piani supplementari (coppie surrogate in UTF-16), perché si divide per unità di codice UTF-16 anziché per punto di codice . L'operatore di diffusione e Array.from()(la mia preferenza) no.
Inkling

@Inkling Non mi rendevo conto che era un problema. Grazie per segnalarlo. Sarei ancora tentato di scrivere una funzione di utilità per chiarezza.
AnnanFay,

19

Sembra che sono in ritardo di 3 anni alla festa ...

Purtroppo non è possibile come è stato sottolineato. Vedi Le stringhe JavaScript sono immutabili? Ho bisogno di un "generatore di stringhe" in JavaScript?

La prossima cosa migliore che puoi fare è creare una "vista" o "wrapper", che prende una stringa e reimplementa qualunque parte dell'API di stringa che stai usando, ma fingendo che la stringa sia invertita. Per esempio:

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"

Il kicker - il seguente è fatto sul posto dalla matematica pura, visitando ogni personaggio una sola volta e solo se necessario:

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

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

Ciò produce risparmi significativi se applicato a una stringa molto grande, se ne stai prendendo solo una porzione relativamente piccola.

Se ne valga la pena (rispetto all'inversione come una copia come nella maggior parte dei linguaggi di programmazione) dipende in larga misura dal caso d'uso e dall'efficacia della reimplementazione dell'API di stringa. Ad esempio, se tutto ciò che vuoi è fare la manipolazione dell'indice di stringa o prendere piccoli slices o substrs, questo ti farà risparmiare spazio e tempo. Se stai pianificando di stampare grandi sezioni o sottostringhe invertite, tuttavia, i risparmi potrebbero essere davvero piccoli, anche peggio di aver fatto una copia completa. Anche la tua stringa "invertita" non avrà il tipo string, anche se potresti essere in grado di fingere questo con la prototipazione.

L'implementazione della demo sopra crea un nuovo oggetto di tipo ReversedString. È prototipato, e quindi abbastanza efficiente, con un lavoro quasi minimo e uno spazio minimo (le definizioni del prototipo sono condivise). Si tratta di un'implementazione pigra che comporta affettature differite. Ogni volta che esegui una funzione come .sliceo .reversed, eseguirà la matematica dell'indice. Infine, quando si estraggono i dati (implicitamente chiamando .toString()o .charCodeAt(...)o qualcosa del genere), applicherà quelle in modo "intelligente", toccando i dati meno possibile.

Nota: l'API di stringa sopra è un esempio e potrebbe non essere implementata perfettamente. Puoi anche usare solo 1-2 funzioni di cui hai bisogno.


13

Esistono molti modi per invertire una stringa in JavaScript. Sto annotando tre modi che preferisco.

Approccio 1: utilizzo della funzione inversa:

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

Approccio 2: ciclo tra i personaggi:

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

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

  return reversed;
}

Approccio 3: utilizzo della funzione di riduzione:

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

Spero che questo possa essere d'aiuto :)


10

Durante un'intervista, mi è stato chiesto di invertire una stringa senza usare variabili o metodi nativi. Questa è la mia implementazione preferita:

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

Breve, semplice, ma lento come l'inferno;)
Tom

13
Zero metodi nativi? Che dire slice? : - /
foglia

1
Uso interessante della ricorsione. Ironia della sorte che è su Stack Overflow. stackoverflow.com/q/2805172/265877
Alex

@Alex, hai ragione. In alcuni casi, l'intervistatore ti chiederà di non utilizzare Array.prototype.reverse().
Daniel,

10

Esistono diversi modi per farlo, è possibile verificare quanto segue,

1. Tradizionale per loop (incremento):

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

2. Tradizionale per loop (decremento):

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. Utilizzo del ciclo for-of

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

4. Utilizzando il metodo array forEach / high order:

function reverseString(str){

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

5. Norma ES6:

function reverseString(str){

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

6. L'ultimo modo:

function reverseString(str){

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

alert(reverseString("Learning JavaScript"));

7. È inoltre possibile ottenere il risultato utilizzando quanto segue,

function reverseString(str){

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


7

In ES6, hai un'altra opzione

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

reverseString('Hello');

6

Questo è il modo più semplice penso

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
È bello che tu abbia incluso un'emoji nel tuo esempio. In modo che vediamo rapidamente che questo chiaramente non funziona per emoji e molti altri caratteri unicode.
Íhor Mé,

Fede, sebbene la tua risposta sia corretta, non sono d'accordo sul fatto che sia il modo più semplice. Le prime numerose risposte che utilizzano Array.prototype.reverse()sarebbe il modo più semplice, quindi la risposta più popolare. Naturalmente, richiederebbe una buona conoscenza preliminare di JavaScript.
Daniel,

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

O

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

// Output: 'gnirts elpmas'


L'intera parte della 'mappa' può essere scritta come [...str].

5

So che questa è una vecchia domanda a cui è stata data una risposta, ma per mio divertimento ho scritto la seguente funzione inversa e ho pensato di condividerla nel caso fosse utile per chiunque altro. Gestisce entrambe le coppie surrogate e i segni combinati:

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('');
}

Tutti i suggerimenti per Mathias, Punycode e vari altri riferimenti per istruirmi sulle complessità della codifica dei caratteri in JavaScript.



3

Se non si desidera utilizzare alcuna funzione integrata. Prova questo

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

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

console.log(newstring);

2

La vera risposta è: non è possibile invertirla in posizione, ma è possibile creare una nuova stringa che è il contrario.

Proprio come un esercizio per giocare con la ricorsione: a volte quando vai a un'intervista, l'intervistatore può chiederti come fare usando la ricorsione, e penso che la "risposta preferita" potrebbe essere "Preferirei non farlo nella ricorsione in quanto può facilmente causare un overflow dello stack "(perché è O(n)piuttosto che O(log n). Se lo è O(log n), è abbastanza difficile ottenere un overflow dello stack - 4 miliardi di articoli potrebbero essere gestiti da un livello di stack di 32, poiché 2 ** 32 è 4294967296. Ma se lo èO(n) , può facilmente ottenere un overflow dello stack.

A volte l'intervistatore ti chiederà ancora, "proprio come un esercizio, perché non lo scrivi ancora usando la ricorsione?" Ed eccolo qui:

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

prova:

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

produzione:

999elppa899elppa...2elppa1elppa0elppa

Per provare a ottenere un overflow dello stack, sono passato 1000a 10000Google Chrome e ho segnalato:

RangeError: Maximum call stack size exceeded

2

Le stringhe stesse sono immutabili, ma puoi facilmente creare una copia invertita con il seguente codice:

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
Ciò ha il vantaggio di gestire correttamente i caratteri del piano supplementare.

2

Una piccola funzione che gestisce sia la combinazione di segni diacritici che caratteri a 2 byte:

(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() ); }
);
  


Aggiornare

Un elenco più completo di combinazione dei segni diacritici è:

      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);
      };

Un degno tentativo, ma se dovessi scansionare il file UnicodeData.txt, scopriresti che ci sono 316 di tali intervalli di combinazione di segni diacritici, piuttosto che 5.
Mr Lister

@MrLister La soluzione è quindi quella di modificare la isCombiningDiacriticfunzione per includere tutti gli intervalli 316; sentiti libero di fornire quella modifica poiché sembra che tu abbia i dati a portata di mano.
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

senza convertire la stringa in array;

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());

usando Array.reverse senza convertire i caratteri in punti di codice;

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());

Per la seconda versione: var c = array[i-1]; array[i-1] = array[i]; array[i] = c;non richiede la concatenazione della coppia di codici. Inoltre, il for-loop dovrebbe iniziare alle 1.
MT0

La seconda versione non funziona con '\ud83c\ud83c\udfa5'.reverse()- emetterà lo stesso input. L'aggiunta ++i;all'interno ifdell'istruzione dovrebbe risolvere questo problema.
MT0

Ripensandoci, questo non gestisce la combinazione dei segni diacritici: 'a\u0303bc'.reverse() === 'cba\u0303'dovrebbe tornare vero.
MT0,

1

Penso che String.prototype.reverse sia un buon modo per risolvere questo problema; il codice come di seguito;

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

Utilizzando le funzioni di array,

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);

Come è "sul posto" ??
Sudhansu Choudhary,

1

Il mio tentativo originale ...

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

Keep it DRY e semplice sciocco !!

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, abbastanza semplice, puoi creare una funzione con un semplice ciclo per invertire la stringa senza usare reverse(),charAt() ecc. In questo modo:

Ad esempio hai questa stringa:

var name = "StackOverflow";

Crea una funzione come questa, la chiamo 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;
}

E puoi chiamarlo come:

reverseString(name);

E il risultato sarà:

"wolfrevOkcatS"

1

Il modo migliore per invertire una stringa in JavaScript

1) Array.reverse:

Probabilmente stai pensando, aspetta che pensassi che stessimo invertendo una stringa, perché stai usando il metodo Array.reverse. Usando il metodo String.split stiamo convertendo la nostra stringa in una matrice di caratteri. Quindi stiamo invertendo l'ordine di ciascun valore nell'array e infine riconvertiamo l'array in una stringa utilizzando il metodo Array.join.

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

2) Decelerazione while-loop:

Sebbene piuttosto dettagliata, questa soluzione presenta i suoi vantaggi rispetto alla soluzione 1. Non stai creando un array e stai concatenando una stringa basata su caratteri della stringa di origine.

Dal punto di vista delle prestazioni, questo probabilmente produrrebbe i migliori risultati (anche se non testati). Per stringhe estremamente lunghe, tuttavia, i guadagni in termini di prestazioni potrebbero cadere dalla finestra.

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

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


    return temp;
}
reverseString('dwayne');

3) Ricorsione

Adoro quanto sia semplice e chiara questa soluzione. Puoi vedere chiaramente che i metodi String.charAt e String.substr vengono utilizzati per passare attraverso un valore diverso chiamando se stesso ogni volta fino a quando la stringa è vuota di cui il ternario restituirebbe semplicemente una stringa vuota invece di utilizzare la ricorsione per chiamarsi . Ciò produrrebbe probabilmente la seconda migliore prestazione dopo la seconda soluzione.

function reverseString(str) {
    return (str === '') ? '' : reverseString(str.substr(1)) + str.charAt(0);
}
reverseString('dwayne');
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.