2012-05-25 8 views
22

Ho trovato molte domande correlate con risposte che parlano di ... in loop e utilizzando hasOwnProperty ma niente di ciò che faccio funziona correttamente. Tutto quello che voglio fare è controllare se esiste o meno una chiave in una matrice e in caso contrario, aggiungerla.come impedire l'aggiunta di chiavi duplicate a un array javascript

Inizio con un array vuoto, quindi aggiungo chiavi mentre la pagina viene cancellata con jQuery.

Inizialmente, ho sperato che qualcosa di semplice come il seguente dovrebbe funzionare: (utilizzando nomi generici)

if (!array[key]) 
    array[key] = value; 

No Go. Seguito in su con:

for (var in array) { 
    if (!array.hasOwnProperty(var)) 
     array[key] = value; 
} 

cercato anche:

if (array.hasOwnProperty(key) == false) 
    array[key] = value; 

Niente di tutto questo ha funzionato. O nulla viene spinto all'array o quello che provo non è migliore del semplice dichiarare array[key] = value Perché è così semplice fare qualcosa di così semplice. Qualche idea per far funzionare questo?

+3

si sta provando su 'Matrice' o' Oggetto'? – thecodeparadox

+0

ES6 ora ha [Set] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) nativo – Efren

risposta

32

generale, questo è meglio compiuto con un oggetto al posto poiché JavaScript in realtà non hanno array associativi:

var foo = { bar: 0 }; 

Quindi utilizzare in per verificare la presenza di un tasto:

if (!('bar' in foo)) { 
    foo['bar'] = 42; 
} 

Come era Giustamente sottolineato nei commenti qui sotto, questo metodo è utile solo quando le vostre chiavi saranno stringhe, o elementi che possono essere rappresentati come stringhe (come i numeri).

+2

... assumendo che i propri valori siano stringhe o rappresentabili come stringhe univoche (questo include numeri). – Phrogz

+0

@Phrogz Assolutamente. Un bel po 'di consigli per l'OP. – Sampson

+3

Grazie Jonathan. La luce FINALMENTE ha fatto clic su ciò che stavo facendo male. Stavo per dire che la tua risposta non è stata d'aiuto, ma dopo un po 'più di lavoro investigativo, sono lieto di dire che ha funzionato perfettamente. E grazie per i suggerimenti sugli oggetti. Lo terrò a mente in fondo alla strada. – iamsar

21
var a = [1,2,3], b = [4,1,5,2]; 

b.forEach(function(value){ 
    if (a.indexOf(value)==-1) a.push(value); 
}); 

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

Per maggiori dettagli leggere su Array.indexOf.

Se si vuole fare affidamento su jQuery, invece utilizzare jQuery.inArray:

$.each(b,function(value){ 
    if ($.inArray(value,a)==-1) a.push(value); 
}); 

Se tutti i valori sono semplicemente e unicamente rappresentabile come stringhe, tuttavia, è necessario utilizzare un oggetto invece di un array, per un potenziale aumento di velocità(come descritto nella risposta di @ JonathanSampson).

+0

Inoltre, il problema con l'uso di 'indexOf' è che esso stesso crea un loop ... Questo rende un [Schlemiel l'algoritmo del pittore] (http://en.wikichip.org/wiki/Schlemiel_the_Painter's_Algorithm) che rallenta con ogni elemento aggiunto all'array. –

0

La logica è sbagliata. Considerate questo:

x = ["a","b","c"] 
x[0]  // "a" 
x["0"] // "a" 
0 in x // true 
"0" in x // true 
x.hasOwnProperty(0) // true 
x.hasOwnProperty("0") // true 

Non v'è alcun motivo di ciclo per verificare la presenza di chiave (o indici per gli array) esistenza. Ora, i valori sono una storia diversa ...

Felice di codifica

0
function check (list){ 
    var foundRepeatingValue = false; 
    var newList = []; 
    for(i=0;i<list.length;i++){ 
     var thisValue = list[i]; 
     if(i>0){ 
      if(newList.indexOf(thisValue)>-1){ 
       foundRepeatingValue = true; 
       console.log("getting repeated"); 
       return true; 
      } 
     } newList.push(thisValue); 
    } return false; 
} 

 

var list1 = ["dse","dfg","dse"]; 
check(list1); 

uscita:

getting repeated 
true