2012-12-12 55 views
8

Devo eseguire una funzione in JavaScript che rimuove tutte le lettere duplicate in una stringa. Finora sono stato in grado di farlo: se ho la parola "anaconda" mi mostra come risultato "anaconda" quando dovrebbe mostrare "cod". Ecco il mio codice:Rimuovere i caratteri duplicati dalla stringa

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')); 
+0

Sembra che vi manca un po 'di codice? jsfiddle.net è ottimo anche per questo tipo di domande. – WildCrustacean

+3

http://jsfiddle.net/mplungjan/FHUgY/ funziona per me - Ottengo il granaio – mplungjan

+0

me, anche IE 8 – nozzleman

risposta

7

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'));

Se si desidera solo tornare caratteri che appaiono si verificano una volta in una stringa, controllare se la loro ultima occorrenza è nella stessa posizione come la loro prima occorrenza .

Il codice restituiva tutti i caratteri nella stringa almeno una volta, anziché solo i caratteri di ritorno che si verificano non più di una volta. ma ovviamente si sa che già, altrimenti non ci sarebbe una domanda ;-)

+1

Invece di downvoting una delle risposte più efficienti su questo domanda che si lamenta della complessità, che ne dici se aggiungi la tua risposta che non ha complessità n^2, @ZacB? Non dire a qualcuno di riscrivere completamente la risposta senza ___almeno___ dando alcuni suggerimenti. Non è costruttivo, e francamente, maleducato. – Cerbrus

+0

'lastIndexOf' e' indexOf' sono operazioni O (N) (dove N è la lunghezza della stringa di input). Molte implementazioni di motori/stringhe JS nascondono questi contenuti o stringhe di back con i dizionari, ma ciò non avviene al 100% delle volte e non è un dato. Meglio scambiare lo spazio temporaneo e usare un oggetto come fanno le altre risposte. Si potrebbe alleviare lo svantaggio dello spazio mutando la stringa di input, ma la copia implicata lì lo rende una specie di punto controverso. –

+2

Come ho detto, fornisci una tua risposta. Non dire semplicemente a qualcuno di riscrivere completamente una risposta _working, upvoted_ solo perché non è efficiente come dovrebbe essere. – Cerbrus

0

Ho FF/Chrome, su cui questo funziona:

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

Quale è possibile riutilizzare se si scrive un funzione come:

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(""); 
} 

per browser meno recenti che la mancanza map, filter ecc, sto cercando di indovinare che potrebbe essere emulato da jQuery o prototipo ...

+0

A parte la compatibilità tra i browser "urti", le operazioni di array come quelle sono [relativamente lente] (http://jsperf.com/unique-in-string). – Cerbrus

+0

@Cerbrus Non sorprende. Probabilmente scriverò qualcosa come hai fatto se avessi usato questo in loop stretti o dappertutto. Solo che è bello avere un esempio dichiarativo - ci potrebbero essere acquirenti se lo vogliono di più per la comprensione critica, piuttosto che le sezioni di codice critico per le prestazioni ... Grazie per il benchmark! – Faiz

+0

In effetti, è sempre bello avere più soluzioni sulle risposte qui, anche se alcune soluzioni vengono brutalmente ridotte a zero senza un motivo apparente. (prova ad offrire una soluzione non jQuery quando alcune jQueries hanno ottenuto 5 voti) ;-) C'è sempre più strade per Roma. – Cerbrus

0

Ancora un altro modo per rimuovere tutte le lettere che compaiono più di una volta:

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; 
} 

Live test case.

Spiegazione: si esegue il ciclo una volta su tutti i caratteri nella stringa, associando ciascun carattere alla quantità di volte in cui si è verificato nella stringa. Quindi esegui iterazioni sugli oggetti (lettere che compaiono nella stringa) e scegli solo quelli che apparivano una sola volta.

+0

Con 2 loop e un oggetto temporaneo, questo mi sembra un po 'un goldberg rube. – Cerbrus

+0

Sì, buona idea, ma potrebbe essere implementato in un ciclo con un sostituto – mplungjan

+0

grazie, ma c'è un altro modo per digitare (var letter in mapping) perché non capisco davvero quella parte –

0
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(''); 
} 
1

DEMO

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 
​ 
0

Questo codice ha funzionato per me sulla rimozione duplicare caratteri (ripetute) da una stringa (anche se le sue parole separate da uno spazio)

Link: Working Sample 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

Ecco cosa ho usato: non l'ho provato per spazi o spe personaggi ufficiali, ma dovrebbero funzionare bene per le stringhe puri:

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

OP desidera che tutti i caratteri che appaiono più di una volta vengano rimossi. Per '" anaconda "', richiede '" cod "' come output. La tua funzione restituisce '" ancod "'. – Cerbrus

-1
function RemDuplchar(str) 
{ 
    var index={},uniq='',i=0; 
    while(i<str.length) 
    { 
     if (!index[str[i]]) 
     { 
     index[str[i]]=true; 
     uniq=uniq+str[i]; 
     } 
      i++; 
    } 
    return uniq; 
} 
+0

OP desidera rimuovere tutti i caratteri visualizzati più volte. Per '" anaconda "', richiede '" cod "' come output. La tua funzione restituisce '" ancod "'. – Cerbrus

3

Possiamo cose ora anche pulite fino utilizzando il metodo del filtro:

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

esempio di lavoro: https://jsfiddle.net/masterspambot/ppz6uec1/

-1

Possiamo rimuovere il duplicato o elementi simili nella stringa usando il ciclo for ed estraendo metodi di stringa come slice, substring, substr

esempio, se si desidera rimuovere gli elementi duplicati quali aababbafabbb:

var data = document.getElementById("id").value 
for(var i = 0; i < data.length; i++) 
{ 
    for(var j = i + 1; j < data.length; j++) 
    { 
     if(data.charAt(i)==data.charAt(j)) 
     { 
      data = data.substring(0, j) + data.substring(j + 1); 
      j = j - 1; 
      console.log(data); 
     } 
    } 
} 

Per favore fatemi sapere se si desidera che alcune informazioni aggiuntive.

+0

OP vuole che tutti i caratteri che appaiono più di una volta vengano rimossi. Per '" anaconda "', richiede '" cod "' come output. La tua funzione restituisce '" ancod "'. – Cerbrus

0

Appena trovato un problema simile (trovare i duplicati). In sostanza, utilizzare un hash per tenere traccia dei conti carattere occorrenza, e costruire una nuova stringa con i "one-hit wonder":

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; 
} 

Uso:

var a = "anaconda"; 
var b = oneHitWonders(a); // b === "cod" 
3

Volevo solo aggiungere la mia soluzione per il divertimento:

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; 
} 
2
//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 
0

Con lodash:

_.uniq('baraban').join(''); // returns 'barn' 
0

provare questo codice, funziona :)

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

Questo dovrebbe funzionare utilizzando Regex;
NOTA: In realtà, non so come funziona questa regex, ma conoscevo la sua 'stenografia', quindi, vorrei spiegarti meglio il significato di questo /(.+)(?=.*?\1)/g;. questa regex restituisce solo il carattere duplicato in un array, quindi l'ho passato in loop per ottenere la lunghezza dei caratteri ripetuti.ma questo non funziona per caratteri speciali come "#" "_" "-", ma fornisce risultati attesi; compresi quelli caratteri speciali 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'espressione regolare /([a-zA-Z])\1+$/ è alla ricerca di:

([a-zA-Z]]) - Una lettera che si coglie nel primo gruppo; poi \1+ - immediatamente dopo una o più copie di quella lettera; poi $ - la fine della stringa. sostituendolo a /([a-zA-Z]).*?\1/ cerca invece:

([a-zA-Z]) - Una lettera che cattura nel primo gruppo; quindi .*? - zero o più caratteri (il simbolo? indica il minor numero possibile); fino a \1 - trova una ripetizione del primo carattere abbinato.

0
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"] 

Controllare qui: https://jsfiddle.net/jmgy8eg9/1/

Problemi correlati