web-dev-qa-db-fra.com

Comment inverser une chaîne en place en JavaScript?

Comment inverser une chaîne en place (ou sur place) en JavaScript lorsqu'elle est transmise à une fonction avec une instruction return? Tout cela sans utiliser les fonctions intégrées? .reverse(), .charAt(), etc.

379
Jake

Tant que vous utilisez des caractères ASCII simples et que vous utilisez les fonctions intégrées, cela fonctionnera:

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

Si vous avez besoin d'une solution prenant en charge UTF-16 ou d'autres caractères multi-octets, sachez que cette fonction donnera des chaînes unicode non valides, ou des chaînes valides au look amusant. Vous voudrez peut-être envisager cette réponse à la place .

681
belacqua

La technique suivante (ou similaire) est couramment utilisée pour inverser une chaîne en JavaScript:

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

En fait, toutes les réponses affichées jusqu’à présent sont une variation de ce schéma. Cependant, cette solution pose quelques problèmes. Par exemple:

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

Si vous vous demandez pourquoi cela se produit, lisez le code interne de JavaScript . (TL; DR: ???? est un symbole astral et JavaScript l'expose sous forme de deux unités de code distinctes.)

Mais il y a plus:

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

Une bonne chaîne pour tester les implémentations inverses de chaîne est la suivante :

'foo ???? bar mañana mañana'

Pourquoi? Parce qu’il contient un symbole astral (????) (qui sont représentés par des paires de substitution en JavaScript ) et une marque de combinaison (le du dernier mañana est en fait composé de deux symboles: U + 006E LETTRE MINUSCULE LATINE N et U + 0303 COMBINAISON DE TILDE).

L’ordre dans lequel les paires de substitution apparaissent ne peut pas être inversé, sinon le symbole astral n’apparaîtra plus dans la chaîne «inversée». C’est pourquoi vous avez vu ces marques �� dans la sortie de l’exemple précédent.

Les marques de combinaison sont toujours appliquées au symbole précédent. Vous devez donc traiter le symbole principal (L + L6 Petite Lettre Latine U + U) comme de la marque de combinaison (U + 0303 Combiner Tile) dans son ensemble. Si vous inversez leur ordre, la marque de combinaison sera associée à un autre symbole de la chaîne. C’est pourquoi l’exemple de sortie comportait au lieu de ñ.

Espérons que cela explique pourquoi toutes les réponses postées jusqu’à présent sont faux.


Pour répondre à votre question initiale - comment inverser [correctement] une chaîne en JavaScript -, j’ai écrit une petite bibliothèque JavaScript capable d’inverser la chaîne Unicode. Il n’a aucun des problèmes que je viens de mentionner. La bibliothèque s'appelle Esrever ; son code est sur GitHub, et il fonctionne dans pratiquement tous les environnements JavaScript. Il est livré avec un utilitaire/binaire Shell, de sorte que vous pouvez facilement inverser les chaînes de votre terminal si vous le souhaitez.

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

Pour la partie «en place», voir les autres réponses.

387
Mathias Bynens
String.prototype.reverse=function(){return this.split("").reverse().join("");}

ou

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

Analyse détaillée et dix façons différentes d'inverser une chaîne et ses détails de performance.

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

Performance de ces implémentations:

Meilleure implémentation (s) par navigateur

  • Chrome 15 - Implémentations 1 et 6 
  • Firefox 7 - Mise en oeuvre 6 
  • IE 9 - Mise en oeuvre 4 
  • Opera 12 - Mise en oeuvre 9

Voici ces implémentations:

Mise en oeuvre 1:

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

Mise en œuvre 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('');
}

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

Mise en oeuvre 4:

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

Mise en oeuvre 5:

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

Mise en oeuvre 6:

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

Mise en œuvre 7:

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

Mise en oeuvre 8:

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

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

Mise en oeuvre 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));
}
50
Anil Arrabole

Tout le «renversement d'une chaîne en place» est une programmation obsolète de la question C avec laquelle les personnes interviewées ont été interviewées (par vengeance peut-être?), Le demanderont. Malheureusement, c’est la partie "En place" qui ne fonctionne plus car les chaînes de pratiquement tous les langages gérés (JS, C #, etc.) utilisent des chaînes immuables, annulant ainsi l’idée de déplacer une chaîne sans allouer de nouvelle mémoire.

Bien que les solutions ci-dessus inversent effectivement une chaîne, elles ne le font pas sans allouer plus de mémoire et ne remplissent donc pas les conditions. Vous devez avoir un accès direct à la chaîne telle qu’attribuée et pouvoir manipuler son emplacement mémoire initial pour pouvoir l’inverser sur place.

Personnellement, je déteste vraiment ce genre de questions d’entrevue, mais malheureusement, je suis sûr que nous continuerons à les voir pendant des années.

50
Mozleron

Commencez par utiliser Array.from() pour transformer une chaîne en tableau, puis/ Array.prototype.reverse() pour inverser le tableau, puis Array.prototype.join() pour le transformer en chaîne.

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

Dans ECMAScript 6, vous pouvez inverser une chaîne encore plus rapidement sans utiliser la méthode de division .split(''), avec l'opérateur spread de cette façon: 

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

On dirait que j'ai 3 ans de retard à la fête ...

Malheureusement, vous ne pouvez pas comme cela a été souligné. Voir Les chaînes JavaScript sont-elles immuables? Ai-je besoin d'un "constructeur de chaînes" en JavaScript?

La meilleure chose à faire est de créer une "vue" ou un "wrapper", qui prend une chaîne et réimplémente toutes les parties de l'API de chaîne que vous utilisez, mais en prétendant que la chaîne est inversée. Par exemple:

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

Démo:

> 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"

Le kicker - ce qui suit est fait sur place par des mathématiques pures, en visitant chaque personnage une seule fois, et seulement si nécessaire:

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

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

Cela permet de réaliser des économies substantielles s’il est appliqué à une très grande chaîne, si vous ne prenez qu’une tranche relativement petite de celle-ci.

Que cela vaille la peine (inverser la copie, comme dans la plupart des langages de programmation) dépend fortement de votre cas d'utilisation et de l'efficacité avec laquelle vous réimplémentez l'API string. Par exemple, si vous souhaitez simplement manipuler les index de chaînes ou utiliser de petits slices ou substrs, vous gagnerez du temps et de l'espace. Toutefois, si vous prévoyez d’imprimer de grandes tranches inversées ou des sous-chaînes, les économies réalisées sont peut-être minimes, voire pires qu’une copie complète. Votre chaîne "inversée" n'aura pas non plus le type string, mais vous pourrez peut-être simuler cela avec le prototypage.

L'implémentation de démonstration ci-dessus crée un nouvel objet de type ReversedString. Il est prototypé et donc assez efficace, avec un travail presque minimal et un encombrement en espace minimal (les définitions de prototype sont partagées). C'est une implémentation paresseuse impliquant un découpage différé. Chaque fois que vous exécutez une fonction telle que .slice ou .reversed, les mathématiques de l'index sont exécutées. Enfin, lorsque vous extrayez des données (en appelant implicitement .toString() ou .charCodeAt(...) ou quelque chose du genre), elles seront appliquées de manière "intelligente", en touchant le moins de données possible.

Remarque: la chaîne API ci-dessus est un exemple et peut ne pas être implémentée parfaitement. Vous pouvez également utiliser seulement 1-2 fonctions dont vous avez besoin.

19
ninjagecko

Au cours d'une interview, on m'a demandé d'inverser une chaîne sans utiliser de variables ni de méthodes natives. Ceci est mon implémentation préférée:

function reverseString(str) {
    return str === '' ? '' : reverseString(str.slice(1)) + str[0];
}
10
Alex Hawkins
var str = 'sample string';
[].map.call(str, function(x) {
  return x;
}).reverse().join('');

OR

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

// Sortie: 'gnirts elpmas'

6
Yogesh

C'est le moyen le plus simple je pense

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

6
Fatih

Il y a plusieurs façons de le faire, vous pouvez vérifier ce qui suit,

1. Traditionnel pour boucle (incrémentation):

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

2. Traditionnel pour boucle (décrémentation):

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. Utilisation de la boucle for-of

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

4. Utilisation de la méthode forEach/high order array:

function reverseString(str){

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

5. Norme ES6:

function reverseString(str){

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

6. La dernière façon:

function reverseString(str){

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

alert(reverseString("Learning JavaScript"));

7. Vous pouvez également obtenir le résultat en utilisant ce qui suit,

function reverseString(str){

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

6
Maher Hossain

Je sais que c’est une vieille question à laquelle on a bien répondu, mais pour mon propre amusement, j’ai écrit la fonction inverse suivante et je pensais la partager si elle était utile à quelqu'un d’autre. Il gère les deux paires de substitution et les marques combinées:

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

Tous les accessoires de Mathias, Punycode et diverses autres références m'ont éclairé sur la complexité de l'encodage des caractères en JavaScript.

5
Scott Gartner

Il y a plusieurs façons d'inverser une chaîne en JavaScript. Je note trois façons que je préfère.

Approche 1 en utilisant la fonction inverse:

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

Approche 2 en boucle à travers les personnages:

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

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

  return reversed;
}

Approche 3 en utilisant la fonction de réduction:

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

J'espère que ça aide :)

4

Dans ES6, vous avez encore une option

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

reverseString('Hello');
4
Dava E.

Vous ne pouvez pas parce que les chaînes JS sont immuables. Solution courte non-en place

[...str].reverse().join``
let str = "Hello World!";
let r = [...str].reverse().join``;
console.log(r);
2
Kamil Kiełczewski

La vraie réponse est la suivante: vous ne pouvez pas l'inverser sur place, mais vous pouvez créer une nouvelle chaîne qui est l'inverse.

Juste comme exercice pour jouer avec la récursion: parfois, lorsque vous vous présentez à une interview, l’interviewer peut vous demander comment faire cela en utilisant la récursivité, et je pense que la "réponse préférée" pourrait être "Je préférerais ne pas le faire en récursivité peut facilement provoquer un débordement de pile "(car il s’agit de O(n) et non de O(log n). Si c'est O(log n), il est assez difficile d’obtenir un débordement de pile - 4 milliards d’éléments pourraient être gérés par un niveau de pile de 32, soit 2 ** 32 est 4294967296. Mais si c'est O(n), alors il peut facilement avoir un débordement de pile.

Parfois, l'intervieweur vous demandera toujours "juste comme exercice, pourquoi ne l'écrivez-vous toujours pas en utilisant la récursivité?" Et le voici:

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

essai:

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

sortie:

999elppa899elppa...2elppa1elppa0elppa

Pour essayer d'obtenir un débordement de pile, j'ai remplacé 1000 en 10000 dans Google Chrome.

RangeError: Maximum call stack size exceeded
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
2
alejandro

Les chaînes elles-mêmes sont immuables, mais vous pouvez facilement créer une copie inversée avec le code suivant:

function reverseString(str) {

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

  var strReverse = strArray.join("");

  return strReverse;
}

reverseString("hello");
2

Si vous ne voulez utiliser aucune fonction intégrée. Essaye ça

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

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

        console.log(newstring)
2
jitendra rajput

Je pense que String.prototype.reverse est un bon moyen de résoudre ce problème. Le code ci-dessous;

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
jingyinggong

Gardez-le DRY et simple idiot!

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
Sagar Munjal
function reverseString(string) {
    var reversedString = "";
    var stringLength = string.length - 1;
    for (var i = stringLength; i >= 0; i--) {
        reversedString += string[i];
    }
    return reversedString;
}
1
GR1000

Ma propre tentative 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
AntonB

sans convertir chaîne en tableau;

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

utiliser Array.reverse sans convertir les caractères en points de code;

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

Les meilleurs moyens d'inverser une chaîne en JavaScript

1) tableau.reverse:

Vous pensez probablement, attendez, je pensais que nous inversions une chaîne, pourquoi utilisez-vous la méthode Array.reverse. En utilisant la méthode String.split, nous convertissons notre chaîne en un tableau de caractères. Ensuite, nous inversons l’ordre de chaque valeur dans le tableau et nous convertissons finalement le tableau en chaîne en utilisant la méthode Array.join.

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

2) Décrémentation de la boucle while:

Bien que très verbeuse, cette solution a ses avantages par rapport à une solution. Vous ne créez pas de tableau et vous concaténez une chaîne basée sur des caractères de la chaîne source.

Du point de vue des performances, celui-ci donnerait probablement les meilleurs résultats (bien que non testé). Pour les chaînes extrêmement longues, les gains de performances risquent toutefois de disparaître.

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

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


    return temp;
}
reverseString('dwayne');

3) Récursion

J'aime à quel point cette solution est simple et claire. Vous pouvez clairement voir que les méthodes String.charAt et String.substr sont utilisées pour transmettre une valeur différente en s’appelant à chaque fois jusqu'à ce que la chaîne soit vide et que le ternaire renvoie simplement une chaîne vide au lieu d'utiliser la récursivité pour s'appeler . Cela donnerait probablement la deuxième meilleure performance après la deuxième solution.

function reverseString(str) {
    return (str === '') ? '' : reverseString(str.substr(1)) + str.charAt(0);
}
reverseString('dwayne');
1
Mohit Kumar Gupta

OK, assez simple, vous pouvez créer une fonction avec une simple boucle pour inverser la chaîne pour vous sans utiliser reverse(), charAt() etc. comme ceci:

Par exemple, vous avez cette chaîne:

var name = "StackOverflow";

Créez une fonction comme celle-ci, je l’appelle 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;
}

Et vous pouvez l'appeler comme ceci:

reverseString(name);

Et le résultat sera:

"wolfrevOkcatS"
1
Alireza

Utilisation des fonctions de tableau,

String.prototype.reverse = function(){
    return [].reduceRight.call(this, function(last, secLast){return last + secLast});
}
1
Darshan
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);
1
Robin

Voici les quatre méthodes les plus courantes que vous pouvez utiliser pour obtenir une inversion de chaîne

Étant donné une chaîne, retourne une nouvelle chaîne avec l'ordre inverse des caractères

Plusieurs solutions au problème

//reverse('Apple') === 'leppa'
//reverse('hello') === 'olleh'
//reverse('Greetings!') === '!sgniteerG'

// 1. First method without using reverse function and negative for loop
function reverseFirst(str) {
    if(str !== '' || str !==undefined || str !== null) {
        const reversedStr = [];
        for(var i=str.length; i>-1; i--) {
        reversedStr.Push(str[i]);
        }
    return reversedStr.join("").toString();
    }
}

// 2. Second method using the reverse function
function reverseSecond(str) {
    return str.split('').reverse().join('');
}

// 3. Third method using the positive for loop
function reverseThird(str){
    const reversedStr = [];
    for(i=0; i<str.length;i++) {
        reversedStr.Push(str[str.length-1-i])
    }
    return reversedStr.join('').toString();
}

// 4. using the modified for loop ES6
function reverseForth(str) {
    const reversedStr = [];
    for(let character of str) {
        reversedStr = character + reversedStr;
    }
    return reversedStr;
}

// 5. Using Reduce function
function reverse(str) {
    return str.split('').reduce((reversed, character) => {
        return character + reversed;  
    }, '');
}
1
Harshit Pant

Une petite fonction qui combine à la fois des signes diacritiques et des caractères à 2 octets:

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

1
MT0

La liste ci-dessous peut aider toute personne cherchant à inverser une chaîne de manière récursive. A été invité à le faire dans un entretien d'embauche récent en utilisant un style de programmation fonctionnel:

var reverseStr = function(str) {
    return (str.length > 0) ? str[str.length - 1] + reverseStr(str.substr(0, str.length -   1)) : '';
};

//tests
console.log(reverseStr('setab retsam')); //master bates
0
Alex Hawkins
var str = "IAMA JavaScript Developer";
var a=str.split(''), b = a.length;
for (var i=0; i<b; i++) {
    a.unshift(a.splice(1+i,1).shift())
}
a.shift();
alert(a.join(''));
0
Nathan Romano

Quelque chose comme ceci devrait être fait en suivant les meilleures pratiques:

(function(){
	'use strict';
	var str = "testing";
	
	//using array methods
	var arr = new Array();
	arr = str.split("");
	arr.reverse();
	console.log(arr);
	
	//using custom methods
	var reverseString = function(str){
		
		if(str == null || str == undefined || str.length == 0 ){
			return "";
		}
		
		if(str.length == 1){
			return str;
		}
		
		var rev = [];
		for(var i = 0; i < str.length; i++){
			rev[i] = str[str.length - 1 - i];
		}
		return rev;
	} 
	
	console.log(reverseString(str));
	
})();

0
Pritam Banerjee

Vous pouvez essayer quelque chose comme ça. Je suis sûr qu'il y a de la place pour la refactorisation. Je ne pouvais pas me déplacer en utilisant la fonction split. Peut-être que quelqu'un connaît un moyen de le faire sans scission.

Code à mettre en place, peut mettre cela dans votre bibliothèque .js

Code pour l'utiliser (possède un code côté client, uniquement parce qu'il a été testé dans un navigateur):

var sentence = "My Stack is Overflowing."
document.write(sentence.reverseLetters() + '<br />');
document.write(sentence.reverseWords() + '<br />');

Snippet:

String.prototype.aggregate = function(vals, aggregateFunction) {

  var temp = '';
  for (var i = vals.length - 1; i >= 0; i--) {
    temp = aggregateFunction(vals[i], temp);
  }
  return temp;
}

String.prototype.reverseLetters = function() {
  return this.aggregate(this.split(''),
    function(current, Word) {
      return Word + current;
    })
}

String.prototype.reverseWords = function() {
  return this.aggregate(this.split(' '),
    function(current, Word) {
      return Word + ' ' + current;
    })
}

var sentence = "My Stack is Overflowing."
document.write(sentence.reverseLetters() + '<br />');
document.write(sentence.reverseWords() + '<br />');

0
Justin Largey

L'ajout au prototype String est idéal (au cas où il serait ajouté dans le langage JS principal), mais vous devez d'abord vérifier s'il existe et l'ajouter s'il n'existe pas, comme suit:

String.prototype.reverse = String.prototype.reverse || function () {
    return this.split('').reverse().join('');
};
0
charlchad
Word.split('').reduce((acc, curr) => curr+""+acc)
0
Parth Chokshi

Je suppose que cela fonctionnera pour vous

function reverse(str){
    str = str.split("").reverse().join("").split(" ").reverse().join(" ");
    console.log(str)
}
0
M Sohaib Khan

Autre variante (ça marche avec IE?):

String.prototype.reverse = function() {
    for (i=1,s=""; i<=this.length; s+=this.substr(-i++,1)) {}
    return s;
}

MODIFIER:

Ceci est sans l'utilisation de fonctions intégrées:

String.prototype.reverse = function() {
    for (i=this[-1],s=""; i>=0; s+=this[i--]) {}
    return s;
}

Remarque: ceci [-1] contient une longueur de la chaîne.

Cependant, il n'est pas possible d'inverser la chaîne en place, car l'affectation à des éléments de tableau individuels Ne fonctionne pas avec l'objet String (protected?). C'est à dire. vous pouvez faire des assignations, mais la chaîne résultante ne change pas.

0
Thevs
function reverse_string(string)
{
var string;

var len = string.length;

var stringExp = string.split('');
var i;
for (i = len-1; i >=0;i--)
{
var result = document.write(stringExp[i]);
}

return result;
}

reverse_string("This is a reversed string");

// sorties: gnirts desrever a si sihT

0
Steven Mcsorley

Voici un exemple immuable de base de ES6 sans utiliser Array.prototype.reverse:

// :: reverse = String -> String
const reverse = s => [].reduceRight.call(s, (a, b) => a + b)

console.log(reverse('foo')) // => 'oof'
console.log(reverse('bar')) // => 'rab'
console.log(reverse('foo-bar')) // => 'rab-oof'

0
Alan R. Soares
function reverse(str){
var s = "";
for (var i = str.length - 1; i >= 0; i--){
    s += str[i];
}
return s;
};
reverse("your string comes here")
0
Henry Lynx
var reverseString = function(str){ 
  let length = str.length - 1;
  str = str.split('');

  for(let i=0;i<= length;i++){
    str[length + i + 1] = str[length - i];
  }

  return str.splice(length + 1).join('');
}
0
Yazan Rawashdeh