web-dev-qa-db-fra.com

Supprimer les occurrences de mots en double dans une chaîne

Prenez la chaîne suivante à titre d'exemple:

var string = "spanner, span, spaniel, span";

Dans cette chaîne, j'aimerais trouver les mots en double, supprimer tous les doublons en gardant une occurrence du mot en place, puis sortir la chaîne révisée.

Ce qui dans cet exemple serait:

var string = "spanner, span, spaniel";

J'ai installé un jsFiddle pour les tests: http://jsfiddle.net/p2Gqc/

Notez que l'ordre des mots dans la chaîne n'est pas cohérent, pas plus que la longueur de chaque chaîne, donc une expression régulière ne va pas faire le travail ici, je ne pense pas. Je pense à quelque chose dans le sens de la division de la chaîne en un tableau? Mais j'aimerais que ce soit aussi léger que possible sur le client et super rapide ...

11
CLiown

Que diriez-vous quelque chose comme ça?

divisez la chaîne, récupérez le tableau, filtrez-le pour supprimer les éléments en double, rejoignez-les.

var uniqueList=string.split(',').filter(function(item,i,allItems){
    return i==allItems.indexOf(item);
}).join(',');

$('#output').append(uniqueList);

Fiddle

Pour les navigateurs non compatibles, vous pouvez le résoudre en ajoutant ceci dans votre js.

Voir Filtre

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    "use strict";

    if (this == null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var res = [];
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in t)
      {
        var val = t[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, t))
          res.Push(val);
      }
    }

    return res;
  };
}
33
PSL

Si aucune de ces solutions ne fonctionne pour vous, voici une autre solution:

var str = "spanner, span, spaniel, span";
str = str.replace(/[ ]/g,"").split(",");
var result = [];
for(var i =0; i < str.length ; i++){
    if(result.indexOf(str[i]) == -1) result.Push(str[i]);
}
result=result.join(", ");

Ou si vous voulez que sa forme soit meilleure, essayez ceci:

Array.prototype.removeDuplicate = function(){
   var result = [];
   for(var i =0; i < this.length ; i++){
       if(result.indexOf(this[i]) == -1) result.Push(this[i]);
   }
   return result;
}
var str = "spanner, span, spaniel, span";
str = str.replace(/[ ]/g,"").split(",").removeDuplicate().join(", ");
3
Hirad Nikoo
<script type="text/javascript">
str=Prompt("Enter String::","");
arr=new Array();
arr=str.split(",");
unique=new Array();
for(i=0;i<arr.length;i++)
{
    if((i==arr.indexOf(arr[i]))||(arr.indexOf(arr[i])==arr.lastIndexOf(arr[i])))
        unique.Push(arr[i]);   
}
unique.join(",");
alert(unique);
</script>

ce bloc de code supprimera les mots en double d'une phrase.

la première condition de l'instruction if i.e (i == arr.indexOf (arr [i])) inclura la première occurrence d'un mot répétitif dans le résultat (variable unique dans ce code).

la deuxième condition (arr.indexOf (arr [i]) == arr.lastIndexOf (arr [i])) inclura tous les mots non répétitifs.

1
Ashwini Singh

Les deux autres réponses fonctionneraient correctement, bien que la méthode de tableau filter utilisée par PSL ait été ajoutée dans ECMAScript 5 et ne soit pas disponible dans les anciens navigateurs. 

Si vous manipulez des chaînes longues, utiliser $.inArray/Array.indexOf n'est pas le moyen le plus efficace de vérifier si vous avez déjà vu un élément (cela impliquerait d'analyser l'intégralité du tableau à chaque fois). Au lieu de cela, vous pouvez stocker chaque mot sous forme de clé dans un objet et tirer parti des recherches basées sur le hachage, qui seront beaucoup plus rapides que la lecture d'un grand tableau.

var tmp={};
var arrOut=[];
$.each(string.split(', '), function(_,Word){
    if (!(Word in tmp)){
        tmp[Word]=1;
        arrOut.Push(Word);
    }
});
arrOut.join(', ');
1
codebox

Solution alternative utilisant une expression régulière

En utilisant une anticipation positive, vous pouvez enlever tous les mots en double. 

Regex/(\b\S+\b)(?=.*\1)/ig, où 

  • \b - correspond à la limite du mot 
  • \S - correspond au caractère qui n'est pas un espace blanc (tabulations, sauts de ligne, etc.)
  • ?= - utilisé pour une anticipation positive
  • ig - indicateurs pour la recherche globale dans le cas, respectivement
  • +,* - quantificateurs. + -> 1 ou plus, * -> 0 ou plus
  • () - définir un groupe
  • \1 - référence en arrière aux résultats du groupe précédent 

var string1 = 'spanner, span, spaniel, span';
var string2 = 'spanner, span, spaniel, span, span';
var string3 = 'What, the, the, heck';
// modified regex to remove preceding ',' and ' ' as per your scenario 
var result1 = string1.replace(/(\b, \w+\b)(?=.*\1)/ig, '');
var result2 = string2.replace(/(\b, \w+\b)(?=.*\1)/ig, '');
var result3 = string3.replace(/(\b, \w+\b)(?=.*\1)/ig, '');
console.log(string1 + ' => ' + result1);
console.log(string2 + ' => ' + result2);
console.log(string3 + ' => ' + result3);

Le seul inconvénient est que cette expression rationnelle ne conserve que la dernière instance d'un mot dupliqué trouvé et supprime tout le reste. Pour ceux qui ne se soucient que des doublons et non de l'ordre des mots, cela devrait marcher! 

1
Niket Pathak

ci-dessous est un code facile à comprendre et rapide pour supprimer les mots en double dans une chaîne:

var string = "spanner, span, spaniel, span";


var uniqueListIndex=string.split(',').filter(function(currentItem,i,allItems){
    return (i == allItems.indexOf(currentItem));
});

var uniqueList=uniqueListIndex.join(',');

alert(uniqueList);//Result:spanner, span, spaniel

Aussi simple que cela peut résoudre votre problème. J'espère que cela t'aides. À votre santé :)

0
praveenak
// Take the following string
var string = "spanner, span, spaniel, span";
var arr = string.split(", ");
var unique = [];
$.each(arr, function (index,Word) {
    if ($.inArray(Word, unique) === -1) 
        unique.Push(Word);

});

alert(unique);

Live DEMO

0
gdoron

Pour supprimer tous les mots en double, j'utilise ce code:

<script>
function deleteDuplicate(a){a=a.toString().replace(/ /g,",");a=a.replace(/[ ]/g,"").split(",");for(var b=[],c=0;c<a.length;c++)-1==b.indexOf(a[c])&&b.Push(a[c]);b=b.join(", ");return b=b.replace(/,/g," ")};
document.write(deleteDuplicate("g g g g"));
</script>
0
anmml