Comment puis-je compter le nombre de fois qu'une chaîne particulière apparaît dans une autre chaîne. Par exemple, voici ce que j'essaie de faire en Javascript :
var temp = "Ceci est une chaîne.";
alert(temp.count("is")); //devrait afficher '2'
Comment puis-je compter le nombre de fois qu'une chaîne particulière apparaît dans une autre chaîne. Par exemple, voici ce que j'essaie de faire en Javascript :
var temp = "Ceci est une chaîne.";
alert(temp.count("is")); //devrait afficher '2'
Le g
dans l'expression régulière (globale) indique de rechercher dans toute la chaîne plutôt que de trouver juste la première occurrence. Cela correspond à is
deux fois :
var temp = "Ceci est une chaîne.";
var count = (temp.match(/is/g) || []).length;
console.log(count);
Et, s'il n'y a pas de correspondance, cela renvoie 0
:
var temp = "Bonjour le monde !";
var count = (temp.match(/is/g) || []).length;
console.log(count);
Assurez-vous simplement de mettre entre guillemets le mot à rechercher (is
, dans ce cas) s'il contient des caractères spéciaux.
Moderne et élégant, mais la solution de Vitimtk est beaucoup plus efficace. Que pensez-vous tous de son code ?
Cela répond le mieux à la question. Si quelqu'un demandait "Comment puis-je faire cela 10 fois plus rapidement dans un cas spécial (sans regexps)", Vitimtk remporterait cette question.
/** Fonction qui compte les occurrences d'une sous-chaîne dans une chaîne;
* @param {String} string La chaîne
* @param {String} subString La sous-chaîne à rechercher
* @param {Boolean} [allowOverlapping] Optionnel. (Par défaut:false)
*
* @author Vitim.us https://gist.github.com/victornpb/7736865
* @see Test unitaire https://jsfiddle.net/Victornpb/5axuh96u/
* @see https://stackoverflow.com/a/7924240/938822
*/
function occurrences(string, subString, allowOverlapping) {
string += "";
subString += "";
if (subString.length <= 0) return (string.length + 1);
var n = 0,
pos = 0,
step = allowOverlapping ? 1 : subString.length;
while (true) {
pos = string.indexOf(subString, pos);
if (pos >= 0) {
++n;
pos += step;
} else break;
}
return n;
}
occurrences("foofoofoo", "bar"); //0
occurrences("foofoofoo", "foo"); //3
occurrences("foofoofoo", "foofoo"); //1
occurrences("foofoofoo", "foofoo", true); //2
Correspondances:
foofoofoo
1 `----´
2 `----´
J'ai réalisé un test de performance et ma fonction est plus de 10 fois plus rapide que la fonction de recherche par expression régulière postée par gumbo. Dans mon test la chaîne contient 25 caractères avec 2 occurrences du caractère 'o'. J'ai exécuté la fonction 1 000 000 fois dans Safari.
Safari 5.1
Comparatif> Temps total d'exécution: 5617 ms (regexp)
Comparatif> Temps total d'exécution: 881 ms (ma fonction 6.4x plus rapide)
Firefox 4
Comparatif> Temps total d'exécution: 8547 ms (Rexexp)
Comparatif> Temps total d'exécution: 634 ms (ma fonction 13.5x plus rapide)
Modifications que j'ai apportées
longueur de la sous-chaîne mise en cache
ajout d'une conversion de type en chaîne.
ajout d'un paramètre optionnel 'allowOverlapping'
correction de la sortie correcte pour le cas de sous-chaîne vide "".
J'ai répété ce test dans Safari 5 et obtenu des résultats similaires avec une petite chaîne de caractères (100b), mais avec une plus grande chaîne (16ko), l'expression régulière s'est exécutée plus rapidement pour moi. Pour une itération (pas 1 000 000), la différence était de moins d'une milliseconde de toute façon, donc je vote pour l'expression régulière.
+1, mais vous vérifiez substring.length
à chaque boucle, vous devriez envisager de le mettre en cache en dehors du while
@ajax333221 OMG tu lis dans mes pensées, j'ai apporté cette amélioration il y a quelques jours, et j'allais éditer ma réponse jsperf.com/count-string-occurrence-in-string
Ceci est une approche non sécuritaire/inexacte, par exemple: countInstances("isisisisisis", "is") === 0
.
@Antal - Il semble y avoir un bug dans la version bêta précédente de Chrome, cela fonctionne après la mise à jour vers la dernière version. Cependant, je préfèrerais éviter cette méthode.
+1 pour la simplicité et parce que selon mes tests cette solution fonctionne ~10x plus rapidement que les autres!
Comme discuté dans la réponse de @Orbit, les gens obtiennent des résultats différents sur les anciennes versions de Chrome. Je serais peut-être un peu prudent en utilisant cette méthode.
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.
21 votes
Cela dépend de si vous acceptez des instances chevauchantes, par exemple var t = "sss"; Combien d'instances du sous-chaîne "ss" se trouvent dans la chaîne ci-dessus? 1 ou 2? Franchissez-vous chaque instance, ou déplacez-vous le caractère pointeur un par un, en cherchant la sous-chaîne?
4 votes
Un benchmark amélioré pour les réponses à cette question : jsperf.com/string-ocurrence-split-vs-match/2 (basé sur le benchmark de Kazzkiq).
0 votes
Compter le montant total d'un mot spécifique dans une chaîne JavaScript stackoverflow.com/a/65036248/4752258
0 votes
Cette vidéo semble vaguement liée ici - "Entretien de codage de Google avec un ingénieur logiciel de Facebook" - youtube.com/watch?v=PIeiiceWe_w