web-dev-qa-db-fra.com

Supprimer les caractères en double de la chaîne

Je dois créer une fonction en JavaScript qui supprime toutes les lettres dupliquées d'une chaîne. Jusqu'à présent, j'ai été capable de faire ceci: si j'ai le mot "anaconda" il me montre comme résultat "anaconda" alors qu'il devrait afficher "morue" Voici mon code:

function find_unique_characters( string ){
    var unique='';
    for(var i=0; i<string.length; i++){
        if(unique.indexOf(string[i])==-1){
            unique += string[i];
        }
    }
    return unique;
}
console.log(find_unique_characters('baraban'));
10
Zlatko Soleniq
function find_unique_characters(str) {
  var unique = '';
  for (var i = 0; i < str.length; i++) {
    if (str.lastIndexOf(str[i]) == str.indexOf(str[i])) {
      unique += str[i];
    }
  }
  return unique;
}

console.log(find_unique_characters('baraban'));
console.log(find_unique_characters('anaconda'));

Si vous souhaitez uniquement renvoyer des caractères apparaissant une seule fois dans une chaîne, vérifiez si leur dernière occurrence se trouve au même emplacement que la première.

Votre code renvoyait tous les caractères de la chaîne au moins une fois, au lieu de ne renvoyer que des caractères ne figurant pas plus d'une fois. mais évidemment vous le savez déjà, sinon il n'y aurait pas de question ;-)

8
Cerbrus

Nous pouvons aussi maintenant nettoyer les choses en utilisant la méthode de filtrage:

function removeDuplicateCharacters(string) {
  return string
    .split('')
    .filter(function(item, pos, self) {
      return self.indexOf(item) == pos;
    })
    .join('');
}
console.log(removeDuplicateCharacters('baraban'));

Exemple de travail: https://jsfiddle.net/masterspambot/ppz6uec1/

8
masterspambot

Je voulais juste ajouter ma solution pour le plaisir:

function removeDoubles(string) {
  var mapping = {};
  var newString = '';

  for (var i = 0; i < string.length; i++) {
    if (!(string[i] in mapping)) {
      newString += string[i];
      mapping[string[i]] = true;
    }
  }
  return newString;
}
3
Aaron
  //One simple way to remove redundecy of Char in String
       var char = "aaavsvvssff"; //Input string
       var rst=char.charAt(0);
       for(var i=1;i<char.length;i++){              
           var isExist = rst.search(char.charAt(i));
            isExist >=0 ?0:(rst +=  char.charAt(i) ); 
       }
       console.log(JSON.stringify(rst)); //output string : avsf
2
suryadev

D&EACUTE;MO

function find_unique_characters( string ){
    unique=[];
    while(string.length>0){
        var char = string.charAt(0);
        var re = new RegExp(char,"g");
        if (string.match(re).length===1) unique.Push(char);
        string=string.replace(re,"");
    }        
    return unique.join("");
}
console.log(find_unique_characters('baraban')); // rn
console.log(find_unique_characters('anaconda')); //cod
​
1
mplungjan

Avec lodash :

_.uniq('baraban').join(''); // returns 'barn'
1
Lukasz Wiktor

J'ai FF/Chrome, sur lequel cela fonctionne:

var h={}; 
"anaconda".split("").
  map(function(c){h[c] |= 0; h[c]++; return c}).
  filter(function(c){return h[c] == 1}).
  join("")

Que vous pouvez réutiliser si vous écrivez une fonction comme:

function nonRepeaters(s) {
  var h={}; 
  return s.split("").
    map(function(c){h[c] |= 0; h[c]++; return c}).
    filter(function(c){return h[c] == 1}).
    join("");
 }

Pour les navigateurs plus anciens qui manquent de map, filter etc., je suppose que cela pourrait être imité par jQuery ou un prototype ...

0
Faiz

Une autre façon de supprimer toutes les lettres qui apparaissent plus d’une fois:

function find_unique_characters( string ) {
    var mapping = {};
    for(var i = 0; i < string.length; i++) {
        var letter = string[i].toString();
        mapping[letter] = mapping[letter] + 1 || 1;
    }
    var unique = '';
    for (var letter in mapping) {
        if (mapping[letter] === 1)
            unique += letter;
    }

    return unique;
}

Cas de test en direct .

Explication: vous passez en boucle une fois sur tous les caractères de la chaîne, en mappant chaque caractère à la quantité de fois qu'il s'est produit dans la chaîne. Ensuite, vous parcourez les éléments (lettres apparaissant dans la chaîne) et ne sélectionnez que ceux qui ne sont apparus qu'une seule fois.

0
Shadow Wizard

Essayez ce code, ça marche :)

var str="anaconda";
Array.prototype.map.call(str, 
 (obj,i)=>{
  if(str.indexOf(obj,i+1)==-1 && str.lastIndexOf(obj,i-1)==-1){
   return obj;
  }
 }
).join("");
//output: "cod"
0
jayad aadrit

Ce code m'a permis de supprimer les caractères en double (répétés) d'une chaîne (même si ses mots étaient séparés par un espace).

Lien: Exemple de travail JSFiddle

/* This assumes you have trim the string and checked if it empty */
function RemoveDuplicateChars(str) {
   var curr_index = 0;
   var curr_char;
   var strSplit;
   var found_first;
   while (curr_char != '') {
      curr_char = str.charAt(curr_index);
      /* Ignore spaces */
      if (curr_char == ' ') {
         curr_index++;
         continue;
      }
      strSplit = str.split('');
      found_first = false;
      for (var i=0;i<strSplit.length;i++) {
         if(str.charAt(i) == curr_char && !found_first) 
            found_first = true;
         else if (str.charAt(i) == curr_char && found_first) {
            /* Remove it from the string */
            str = setCharAt(str,i,'');
         }
      }
      curr_index++;
   }
   return str;
}
function setCharAt(str,index,chr) {
    if(index > str.length-1) return str;
    return str.substr(0,index) + chr + str.substr(index+1);
}
0
FBN10040
function removeDup(str) {
  var arOut = [];
  for (var i=0; i < str.length; i++) {
    var c = str.charAt(i);
    if (c === '_') continue;
    if (str.indexOf(c, i+1) === -1) {
      arOut.Push(c);
    }
    else {
      var rx = new RegExp(c, "g");
      str = str.replace(rx, '_');
    }
  }
  return arOut.join('');
}
0
closure

Je viens de rencontrer un problème similaire (trouver les doublons). Pour l’essentiel, utilisez un hachage pour suivre le nombre d’occurrences de caractères et créez une nouvelle chaîne avec les "merveilles à un coup":

function oneHitWonders(input) {
    var a = input.split('');
    var l = a.length;
    var i = 0;
    var h = {};
    var r = "";

    while (i < l) {
        h[a[i]] = (h[a[i]] || 0) + 1;

        i += 1;
    }

    for (var c in h) {
        if (h[c] === 1) {
            r += c;
        }
    }

    return r;
}

Utilisation :

var a = "anaconda";
var b = oneHitWonders(a); // b === "cod"
0
thor2k
var str = 'anaconda'.split('');
var rmDup = str.filter(function(val, i, str){
     return str.lastIndexOf(val) === str.indexOf(val);
});
console.log(rmDup); //prints ["c", "o", "d"]

Veuillez vérifier ici: https://jsfiddle.net/jmgy8eg9/1/

0
Hemanth

Voici ce que j'ai utilisé - je ne l'ai pas testé pour les espaces ou les caractères spéciaux, mais cela devrait fonctionner correctement pour les chaînes pures:

function uniquereduce(instring){ 
    outstring = ''
    instringarray = instring.split('')
    used = {}
    for (var i = 0; i < instringarray.length; i++) {
        if(!used[instringarray[i]]){
            used[instringarray[i]] = true
            outstring += instringarray[i]
        }
    }
    return outstring
}
0
asetniop

Cela devrait fonctionner avec Regex;
NOTE: En fait, je ne sais pas comment cette regex fonctionne, mais je connaissais sa "sténographie", alors, je vous expliquerais mieux le sens de cette /(.+)(?=.*?\1)/g;. cette expression rationnelle ne me renvoie que le caractère dupliqué d'un tableau. Je l'ai donc parcouru en boucle pour obtenir la longueur des caractères répétés. Mais cela ne fonctionne pas pour des caractères spéciaux comme "#" "_" "-",, mais donne le résultat attendu; y compris ces caractères spéciaux if any

function removeDuplicates(str){
    var REPEATED_CHARS_REGEX = /(.+)(?=.*?\1)/g;
    var  res = str.match(REPEATED_CHARS_REGEX);
    var Word = res.slice(0,1);
    var raw = res.slice(1);
    var together = new String (Word+raw);
    var fer = together.toString();
    var length = fer.length;
    // my sorted duplicate;
      var result = '';
      for(var i = 0; i < str.length; i++) {
        if(result.indexOf(str[i]) < 0) {
          result += str[i];
        }
      }

      return {uniques: result,duplicates: length};
    } removeDuplicates('anaconda')

L’expression régulière /([a-zA-Z])\1+$/ recherche:

([a-zA-Z]]) - Une lettre qu'il capture dans le premier groupe; puis \1+ - immédiatement après une ou plusieurs copies de cette lettre; then $ - la fin de la chaîne. Le remplacer par /([a-zA-Z]).*?\1/ recherche plutôt:

([a-zA-Z]) - Une lettre qu'il capture dans le premier groupe; then .*? - zéro ou plusieurs caractères (le? indique le moins possible); jusqu'au \1 - il trouve une répétition du premier caractère trouvé.

0
akolliy

J'ai 3 approches sans boucle, une ligne à cela.

Approche 1 - supprime les doublons et préserve l'ordre des caractères d'origine:

var str = "anaconda";
var newstr = str.replace(new RegExp("[^"+str.split("").sort().join("").replace(/(.)\1+/g, "").replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")+"]","g"),"");
//cod

Approche 2 - supprime les doublons mais ne préserve PAS l'ordre des caractères, mais peut être plus rapide que l'approche 1 car elle utilise moins d'expressions régulières:

var str = "anaconda";
var newstr = str.split("").sort().join("").replace(/(.)\1+/g, "");
//cdo

Approche 3 - supprime les doublons, mais conserve les valeurs uniques (ne préserve pas non plus l'ordre des caractères):

var str = "anaconda";
var newstr = str.split("").sort().join("").replace(/(.)(?=.*\1)/g, "");
//acdno
0
user3163495