788 votes

Comment remplacer un caractère à un indice particulier en JavaScript ?

J'ai une chaîne, disons Hello world et je dois remplacer le caractère à l'indice 3. Comment puis-je remplacer un caractère en spécifiant un index ?

var str = "hello world";

J'ai besoin de quelque chose comme

str.replaceAt(0,"h");

268 votes

Ce qui est bizarre c'est que str[0] = 'x' ne semble pas provoquer d'erreurs, mais n'a pas l'effet désiré !

9 votes

@Michael avec cela, vous obtiendriez l'index à 0, le mettriez à 'x', cette déclaration à elle-même renverrait la nouvelle valeur ; 'x'. mais tout cela ne change pas l'original, donc c'est parfaitement valide, juste pas ce que vous attendiez. ce n'est pas une référence

18 votes

@Michael il le fait si "use strict" est activé : Uncaught TypeError: Cannot assign to read only property '0' of string 'hello world' (au moins dans les navigateurs webkit)

854voto

Cem Kalyoncu Points 4740

En JavaScript, les chaînes de caractères sont immuable Ce qui signifie que le mieux que vous puissiez faire est de créer une nouvelle chaîne de caractères avec le contenu modifié et d'assigner la variable pour qu'elle pointe vers elle.

Vous devrez définir le replaceAt() fonction vous-même :

String.prototype.replaceAt = function(index, replacement) {
    return this.substr(0, index) + replacement + this.substr(index + replacement.length);
}

Et utilise-le comme ça :

var hello = "Hello World";
alert(hello.replaceAt(2, "!!")); // He!!o World

189 votes

Notez que ce n'est généralement pas une bonne idée d'étendre les classes JavaScript de base. Utilisez plutôt une simple fonction utilitaire.

102 votes

Je dois demander pourquoi ? Le support des prototypes est là pour ça.

42 votes

@CemKalyoncu : Il peut faire en sorte que le code joue mal avec les autres bibliothèques. Mais je n'ai jamais été mordu par cela moi-même.

165voto

rahul Points 84185

Il n'y a pas replaceAt en JavaScript. Vous pouvez utiliser le code suivant pour remplacer n'importe quel caractère dans n'importe quelle chaîne à la position spécifiée :

function rep() {
    var str = 'Hello World';
    str = setCharAt(str,4,'a');
    alert(str);
}

function setCharAt(str,index,chr) {
    if(index > str.length-1) return str;
    return str.substring(0,index) + chr + str.substring(index+1);
}

<button onclick="rep();">click</button>

0 votes

Je préfère cette solution car elle permet de remplacer un seul caractère. La solution qui a le plus de votes positifs ne fonctionne pas si vous voulez remplacer un seul caractère. Elle ne fonctionne que pour remplacer deux caractères ! En outre, substr devrait être remplacé par substring, comme indiqué dans de nombreux autres commentaires.

1 votes

Dans mes tests, cette méthode était de loin la plus rapide... et encore plus rapide si vous n'avez pas besoin de vérifier que [index] n'est pas plus grand que la longueur de la chaîne. Modifié : function setCharAt(str,idx,newChr){ return str.substring(0,idx)+newChr+str.substring(idx+1);}

1 votes

@ScottTesler - Cette réponse utilise substring pas substr ... et où est-il dit dans votre lien que l'une ou l'autre fonction est "héritée" ou doit être évitée ? ... substring y substr servir différents objectifs .

130voto

Guffa Points 308133

Tu ne peux pas. Prenez les caractères avant et après la position et concattez-les dans une nouvelle chaîne :

var s = "Hello world";
var index = 3;
s = s.substring(0, index) + 'x' + s.substring(index + 1);

0 votes

En fait, oui, vous pouvez, mais ce serait une surenchère. Vous pourriez configurer une expression régulière pour ignorer les premiers caractères de l'index - 1 et faire correspondre le caractère à l'index. Vous pouvez utiliser String.replace avec cette expression régulière pour effectuer un remplacement direct, en place. Mais c'est un peu exagéré. Donc, en pratique, vous ne pouvez pas. Mais en théorie, vous pouvez.

14 votes

@Ates : La fonction replace ne fait pas un remplacement en place, elle crée une nouvelle chaîne et la renvoie.

3 votes

MDN suggère d'utiliser String.prototype.substring sur String.prototype.substr .

38voto

Il y a beaucoup de réponses ici, et toutes sont basées sur deux méthodes :

  • MÉTHODE1 : diviser la chaîne de caractères en deux sous-chaînes et insérer le caractère entre les deux.
  • MÉTHODE 2 : convertir la chaîne en tableau de caractères, remplacer un membre du tableau et le joindre.

Personnellement, j'utiliserais ces deux méthodes dans des cas différents. Laissez-moi vous expliquer.

@FabioPhms : Votre méthode est celle que j'ai initialement utilisée et j'avais peur qu'elle soit mauvaise sur les chaînes de caractères avec beaucoup de caractères. Cependant, la question est : qu'est-ce qu'un grand nombre de caractères ? Je l'ai testé sur 10 paragraphes "lorem ipsum" et cela a pris quelques millisecondes. Ensuite, je l'ai testé sur une chaîne de caractères 10 fois plus grande - il n'y avait vraiment pas de grande différence. Hm.

@vsync, @Cory Mawhorter : Vos commentaires sont sans ambiguïté ; cependant, encore une fois, qu'est-ce qu'une grande chaîne ? Je suis d'accord que pour 32...100kb les performances devraient être meilleures et que l'on devrait utiliser substring-variant pour cette seule opération de remplacement de caractères.

Mais que se passera-t-il si je dois faire plusieurs remplacements ?

J'ai dû effectuer mes propres tests pour prouver ce qui est plus rapide dans ce cas. Disons que nous avons un algorithme qui va manipuler une chaîne de caractères relativement courte, composée de 1000 caractères. Nous pensons qu'en moyenne, chaque caractère de cette chaîne sera remplacé ~100 fois. Donc, le code pour tester quelque chose comme cela est :

var str = "... {A LARGE STRING HERE} ...";

for(var i=0; i<100000; i++)
{
  var n = '' + Math.floor(Math.random() * 10);
  var p = Math.floor(Math.random() * 1000);
  // replace character *n* on position *p*
}

J'ai créé un fiddle pour ça, et c'est aquí . Il y a deux tests, TEST1 (sous-chaîne) et TEST2 (conversion de tableau).

Résultats :

  • TEST1 : 195ms
  • TEST2 : 6ms

Il semble que la conversion de tableau soit plus efficace que la sous-chaîne par deux ordres de grandeur ! Alors - qu'est-ce qui s'est passé ici ???

En fait, toutes les opérations dans TEST2 sont effectuées sur le tableau lui-même, en utilisant une expression d'affectation comme suit strarr2[p] = n . Assignment est vraiment rapide par rapport à substring sur une grande chaîne, et il est clair qu'il va gagner.

Il s'agit donc de choisir le bon outil pour le travail. Encore une fois.

8 votes

J'ai déplacé votre test vers jsperf, avec des résultats très différents : jsperf.com/string-replace-character . Il s'agit de choisir le bon outil pour le travail ;)

1 votes

@colllin : Je suis tout à fait d'accord. J'ai donc presque littéralement cloné les tests de jsfiddle vers jsperf. Cependant, en plus d'utiliser le bon outil, vous devez le faire de la bonne manière. Faites attention au problème, nous parlons de ce qui se passera si nous devons faire un grand nombre de remplacements dans un algorithme. L'exemple concret comprend 10000 remplacements. Cela signifie que un essai devrait inclure 10000 remplacements. Donc, en utilisant jsperf, j'ai obtenu des résultats assez cohérents, voir : jsperf.com/ .

1 votes

C'est pour cela que je n'aime pas javascript. Des cas d'utilisation aussi fréquents, intuitifs et évidents ne sont pas prévus. On pourrait penser que les auteurs de javascript auraient pensé que les gens pourraient vouloir substituer des caractères dans les chaînes de caractères, et qu'ils auraient décidé de mettre des méthodes pratiques dans le langage.

35voto

Fabio Phms Points 1725

Le travail avec les vecteurs est généralement le plus efficace pour contacter String.

Je suggère la fonction suivante :

String.prototype.replaceAt=function(index, char) {
    var a = this.split("");
    a[index] = char;
    return a.join("");
}

Exécutez cet extrait :

String.prototype.replaceAt=function(index, char) {
    var a = this.split("");
    a[index] = char;
    return a.join("");
}

var str = "hello world";
str = str.replaceAt(3, "#");

document.write(str);

11 votes

C'est mauvais pour les grandes chaînes de caractères, pas besoin de créer un tableau avec une quantité folle de cellules si vous pouvez simplement utiliser substr pour le couper...

1 votes

Utile si vous devez changer beaucoup de caractères, et c'est simple.

7 votes

J'ai créé un test sur jsperf : jsperf.com/replace-character-by-index -- Substr est beaucoup plus rapide, et cohérent de 32bytes à 100kb. J'ai upvoted ceci et même si cela me fait mal de le dire, même si cela semble plus agréable, substr est le meilleur choix pour les chaînes de caractères de toute taille.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X