Comment inverser une chaîne en place (ou en place) en JavaScript lorsqu'elle est passée à une fonction avec une instruction return, sans utiliser de fonctions intégrées ( .reverse()
, .charAt()
etc.)?
javascript
string
reverse
Kobe
la source
la source
Réponses:
Tant que vous avez affaire à des caractères ASCII simples et que vous êtes heureux d'utiliser des fonctions intégrées, cela fonctionnera:
Si vous avez besoin d'une solution qui prend en charge UTF-16 ou d'autres caractères multi-octets, sachez que cette fonction donnera des chaînes Unicode invalides ou des chaînes valides qui ont l'air drôles. Vous voudrez peut-être envisager cette réponse à la place .
[... s] est compatible Unicode, une petite modification donne: -
la source
return [...s].reverse().join("");
peut fonctionner.La technique suivante (ou similaire) est couramment utilisée pour inverser une chaîne en JavaScript:
En fait, toutes les réponses publiées jusqu'à présent sont une variation de ce modèle. Cependant, il existe certains problèmes avec cette solution. Par exemple:
Si vous vous demandez pourquoi cela se produit, lisez le codage de caractères interne de JavaScript . (TL; DR:
𝌆
est un symbole astral et JavaScript l'expose comme deux unités de code distinctes.)Mais il y a plus:
Une bonne chaîne pour tester les implémentations inverses de chaînes est la suivante :
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 derniermañana
se compose en fait de deux symboles: U + 006E LETTRE MINUSCULE LATINE N et U + 0303 TILDE COMBINÉE).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 (U + 006E LETTRE MINUSCULE LATINE N) comme la marque de combinaison (U + 0303 TILDE COMBINÉE) 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 avait
ã
au lieu deñ
.Espérons que cela explique pourquoi toutes les réponses publiées jusqu'à présent sont fausses .
Pour répondre à votre question initiale - comment inverser [correctement] une chaîne en JavaScript -, j'ai écrit une petite bibliothèque JavaScript qui est capable d'une inversion de chaîne compatible 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 à peu près n'importe quel environnement JavaScript. Il est livré avec un utilitaire shell / binaire, vous pouvez donc facilement inverser les chaînes de votre terminal si vous le souhaitez.
Quant à la partie «sur place», voir les autres réponses.
la source
ou
la source
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/
Performances de ces implémentations:
Implémentation (s) la plus performante (s) par navigateur
Voici ces implémentations:
Mise en œuvre 1:
Mise en œuvre 2:
Mise en œuvre 3:
Mise en œuvre 4:
Mise en œuvre 5:
Mise en œuvre 6:
Mise en œuvre 7:
Mise en œuvre 8:
Mise en œuvre 9:
Mise en œuvre 10
la source
L'ensemble "inverser une chaîne en place" est une question d'entrevue désuète programmeurs C, et les gens qui ont été interrogés par eux (pour se venger, peut-être?), Demanderont. Malheureusement, c'est la partie "In Place" qui ne fonctionne plus car les chaînes dans à peu près tous les langages gérés (JS, C #, etc.) utilisent des chaînes immuables, défaisant 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'elle est allouée et pouvoir manipuler son emplacement de mémoire d'origine pour pouvoir l'inverser en 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.
la source
Tout d'abord, utilisez
Array.from()
pour transformer une chaîne en tableau, puisArray.prototype.reverse()
pour inverser le tableau, puisArray.prototype.join()
pour en faire une chaîne.la source
reverse
logique préexistante .string.split('')
cela ne fonctionne pas. Voir cette réponse pour plus d'explications.Array.from('foo 𝌆 bar mañana mañana').reverse().join('') == 'anãnam anañam rab 𝌆 oof'
Array.from('foo 𝌆 bar mañana mañana'.normalize('NFC')).reverse().join('')
deviendra"anañam anañam rab 𝌆 oof"
Dans ECMAScript 6, vous pouvez inverser une chaîne encore plus rapidement sans utiliser la
.split('')
méthode de fractionnement, avec l' opérateur d'étalement comme ceci:la source
('')
string.split('')
est plus claire pour la plupart des gens que[...string]
..split('')
a le problème avec les caractères des plans supplémentaires (paires de substitution en UTF-16), car il se divise par unité de code UTF-16 de code plutôt que par point de code . L'opérateur de propagation etArray.from()
(ma préférence) ne le font pas.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 "générateur de chaînes" en JavaScript?
La prochaine meilleure chose que vous pouvez 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 faisant comme si la chaîne était inversée. Par exemple:
Démo:
Le kicker - ce qui suit se fait sur place par des mathématiques pures, en visitant chaque personnage une seule fois, et seulement si nécessaire:
Cela permet de réaliser des économies importantes s'il est appliqué à une très grande chaîne, si vous n'en prenez qu'une portion relativement petite.
Que cela en vaille la peine (par rapport à une inversion en tant que 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 de chaîne. Par exemple, si tout ce que vous voulez, c'est faire une manipulation d'index de chaîne, ou prendre de petits
slice
s ousubstr
s, cela vous fera gagner de l'espace et du temps. Cependant, si vous prévoyez d'imprimer de grandes tranches ou sous-chaînes inversées, les économies peuvent être minimes, voire pire que d'avoir fait une copie complète. Votre chaîne "inversée" n'aura pas non plus le typestring
, bien que vous puissiez être capable de 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 une surcharge d'espace minimale (les définitions des prototypes sont partagées). Il s'agit d'une implémentation paresseuse impliquant un découpage différé. Chaque fois que vous exécutez une fonction comme
.slice
ou.reversed
, il exécute des mathématiques d'index. Enfin, lorsque vous extrayez des données (en appelant implicitement.toString()
ou.charCodeAt(...)
ou quelque chose), il les appliquera de manière "intelligente", en touchant le moins de données possible.Remarque: l'API de chaîne 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.
la source
Il existe de nombreuses façons d'inverser une chaîne en JavaScript. Je note trois façons que je préfère.
Approche 1: Utilisation de la fonction inverse:
Approche 2: boucle à travers les caractères:
Approche 3: Utilisation de la fonction de réduction:
J'espère que ça aide :)
la source
Lors d'une interview, on m'a demandé d'inverser une chaîne sans utiliser de variables ou de méthodes natives. Ceci est ma mise en œuvre préférée:
la source
slice
? : - /Array.prototype.reverse()
.Il existe plusieurs façons de le faire, vous pouvez vérifier les éléments suivants,
1. Traditionnel pour la boucle (incrémentation):
2. Traditionnel pour la boucle (décrémentation):
3. Utilisation de la boucle for-of
4. En utilisant la méthode du tableau forEach / high order:
5. Norme ES6:
6. La dernière façon:
7. Vous pouvez également obtenir le résultat en utilisant ce qui suit,
la source
Dans ES6, vous avez une option de plus
la source
C'est la façon la plus simple, je pense
la source
Array.prototype.reverse()
ce serait le moyen le plus simple, d'où la réponse la plus populaire. Bien sûr, cela nécessiterait une bonne connaissance préalable de JavaScript.OU
// Sortie: 'gnirts elpmas'
la source
[...str]
.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 j'ai pensé la partager au cas où elle serait utile à quelqu'un d'autre. Il gère à la fois les paires de substitution et les marques de combinaison:
Tous les accessoires pour Mathias, Punycode et diverses autres références pour me renseigner sur les complexités de l'encodage de caractères en JavaScript.
la source
Vous ne pouvez pas parce que les chaînes JS sont immuables. Solution courte non en place
Afficher l'extrait de code
la source
Si vous ne souhaitez utiliser aucune fonction intégrée. Essaye ça
la source
La vraie réponse est: vous ne pouvez pas l'inverser en place, mais vous pouvez créer une nouvelle chaîne qui est l'inverse.
Juste comme un exercice pour jouer avec la récursivité: parfois, quand vous allez à une interview, l'intervieweur 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ère ne pas le faire en récursivité car elle peut facilement provoquer un débordement de pile "(car il l'est
O(n)
plutôt queO(log n)
. Si tel est le casO(log n)
, il est assez difficile d'obtenir un débordement de pile - 4 milliards d'éléments pourraient être traités par un niveau de pile de 32, car 2 ** 32 est 4294967296. Mais si c'est le casO(n)
, il peut facilement obtenir un débordement de pile.Parfois, l'intervieweur vous demandera toujours, "juste comme un exercice, pourquoi ne l'écrivez-vous toujours pas en utilisant la récursivité?" Et le voici:
essai:
production:
Pour essayer d'obtenir un débordement de pile, je suis passé
1000
à10000
dans Google Chrome, et il a signalé:la source
Les chaînes elles-mêmes sont immuables, mais vous pouvez facilement créer une copie inversée avec le code suivant:
la source
la source
Inverser une chaîne à l'aide de fonctions intégrées
Inverser une chaîne sans les aides
la source
Une petite fonction qui gère à la fois la combinaison de signes diacritiques et de caractères à 2 octets:
Mise à jour
Une liste plus complète de combinaison de diacritiques est la suivante:
la source
isCombiningDiacritic
fonction pour inclure les 316 plages; n'hésitez pas à fournir cette modification, car vous semblez avoir les données en main.la source
sans convertir la chaîne en tableau;
utiliser Array.reverse sans convertir les caractères en points de code;
la source
var c = array[i-1]; array[i-1] = array[i]; array[i] = c;
ne nécessite pas de concaténation de la paire de codes. De plus, la boucle for devrait commencer à 1.'\ud83c\ud83c\udfa5'.reverse()
- elle produira la même chose que l'entrée. L'ajout++i;
dans l'if
instruction devrait résoudre ce problème.'a\u0303bc'.reverse() === 'cba\u0303'
devrait revenir vrai.Je pense que String.prototype.reverse est un bon moyen de résoudre ce problème; le code comme ci-dessous;
la source
À l'aide des fonctions de tableau,
la source
la source
Ma propre tentative originale ...
http://jsbin.com/bujiwo/19/edit?js,console,output
la source
Gardez-le au sec et simple idiot !!
la source
OK, assez simple, vous pouvez créer une fonction avec une boucle simple pour inverser la chaîne pour vous sans utiliser
reverse()
,charAt()
etc. comme ceci:Par exemple, vous avez cette chaîne:
Créez une fonction comme celle-ci, je l'appelle
reverseString
...Et vous pouvez l'appeler comme:
Et le résultat sera:
la source