2013-08-02 24 views
15

Sto cercando un modo semplice per rimuovere un valore duplicato da un array. Ho capito come rilevare se c'è un duplicato o no, solo che non so come "spingerlo" dal valore. Ad esempio, se vai al link fornito e digita "abca" (premi il tasto invio/invio dopo ogni lettera) .. avviserà "duplicato!"Rimuovi elemento duplicato da array Javascript

Ma voglio anche capire come rimuovere quel duplicato dalla textarea?

http://jsfiddle.net/P3gpp/

questa è la parte che sembra non funzionare ::

sort = sort.push(i); 
textVal = sort; 
return textVal; 

risposta

49

perché farlo nel modo più difficile, si può fare più facilmente utilizzando JavaScript funzione di filtro che è specifico per questo tipo di operazioni:

var arr = ["apple", "bannana", "orange", "apple", "orange"]; 

arr = arr.filter(function(item, index, inputArray) { 
      return inputArray.indexOf(item) == index; 
    }); 


--------------------- 
Output: ["apple", "bannana", "orange"] 
+4

Penso che, nel 2014, cinque anni nell'era di EcmaScript 5 e con IE8 inferiore al 10% della quota mondiale del browser, possiamo tranquillamente chiamare questa la risposta corretta. Se si è interessati al supporto per le vecchie versioni di IE, è possibile utilizzare una libreria di polyfill per EC5. – Semicolon

+1

(Vorrei notare che mentre "filtro" è la risposta giusta il 90% delle volte, non è appropriato da solo nelle circostanze in cui potrebbero esserci riferimenti alla matrice originale altrove perché crea una nuova matrice e l'originale l'oggetto dell'array è rimasto intatto.) – Semicolon

4

Queste sono le funzioni che ho creato/utilizzare per rimuovere i duplicati:

var removeDuplicatesInPlace = function (arr) { 
    var i, j, cur, found; 
    for (i = arr.length - 1; i >= 0; i--) { 
     cur = arr[i]; 
     found = false; 
     for (j = i - 1; !found && j >= 0; j--) { 
      if (cur === arr[j]) { 
       if (i !== j) { 
        arr.splice(i, 1); 
       } 
       found = true; 
      } 
     } 
    } 
    return arr; 
}; 

var removeDuplicatesGetCopy = function (arr) { 
    var ret, len, i, j, cur, found; 
    ret = []; 
    len = arr.length; 
    for (i = 0; i < len; i++) { 
     cur = arr[i]; 
     found = false; 
     for (j = 0; !found && (j < len); j++) { 
      if (cur === arr[j]) { 
       if (i === j) { 
        ret.push(cur); 
       } 
       found = true; 
      } 
     } 
    } 
    return ret; 
}; 

Quindi, utilizzando il primo, ecco come potrebbe apparire il tuo codice:

function cleanUp() { 
    var text = document.getElementById("fld"), 
     textVal = text.value, 
     array; 

    textVal = textVal.replace(/\r/g, " "); 
    array = textVal.split(/\n/g); 

    text.value = removeDuplicatesInPlace(array).join("\n"); 
} 

DEMO:http://jsfiddle.net/VrcN6/1/

+1

Grazie. Funziona molto bene! – Matthew

1

Si può fare questo facilmente con solo un oggetto:

function removeDuplicates(text) { 
    var seen = {}; 
    var result = ''; 

    for (var i = 0; i < text.length; i++) { 
     var char = text.charAt(i); 

     if (char in seen) { 
      continue; 
     } else { 
      seen[char] = true; 
      result += char; 
     } 
    } 

    return result; 
} 

function cleanUp() { 
    var elem = document.getElementById("fld"); 

    elem.value = removeDuplicates(elem.value); 
} 
+0

Considera: 'risultato + = carattere inserito? '': seen [char] = char; ' – RobG

2

È possibile utilizzare Array.reduce() per rimuovere i duplicati. Hai bisogno di un oggetto helper per tenere traccia di quante volte è stato visto un oggetto.

function cleanUp() 
{ 
    var textBox = document.getElementById("fld"), 
    array = textBox.value.split(/\r?\n/g), 
    o = {}, 
    output; 

    output = array.reduce(function(prev, current) { 
     var key = '$' + current; 

     // have we seen this value before? 
     if (o[key] === void 0) { 
      prev.push(current); 
      o[key] = true; 
     } 

     return prev; 
    }, []); 

    // write back the result 
    textBox.value = output.join("\n"); 
} 

L'uscita del passo reduce() può essere utilizzato direttamente per popolare di nuovo l'area di testo, senza alterare l'ordinamento originale.

Demo

0
 arr3 = [1, 2, 3, 2, 4, 5]; 

     unique = []; 

    function findUnique(val) 
    { 
    status = '0'; 
    unique.forEach(function(itm){ 

     if(itm==val) 
     { 
     status=1; 
     } 

       }) 
return status; 
} 

arr3.forEach(function(itm){ 

    rtn = findUnique(itm); 
    if(rtn==0) 
    unique.push(itm); 


    }); 

    console.log(unique); // [1, 2, 3, 4, 5] 
4

Sulla base di user2668376 soluzione, questo restituirà un nuovo array senza duplicati.

Array.prototype.removeDuplicates = function() { 
    return this.filter(function (item, index, self) { 
     return self.indexOf(item) == index; 
    }); 
}; 

Dopo di che si può fare:

[1, 3, 3, 7].removeDuplicates(); 

Risultato sarà; [1, 3, 7].

+0

Quindi, se user2668376 ha già risposto con questa soluzione, perché ripeterlo? A proposito, hai un "io" troppo. – Bergi

+1

La sua soluzione è senza .prototype. Secondo me è molto meglio usarlo. Ho cancellato la var auto = this; –