2012-05-25 8 views
22

Ich habe viele verwandte Fragen mit Antworten gefunden, die über ... in Schleifen sprechen und hasOwnProperty verwenden, aber nichts, was ich richtig mache. Alles, was ich tun möchte, ist zu überprüfen, ob ein Schlüssel in einem Array existiert oder nicht, und wenn nicht, füge ihn hinzu.Wie man das Hinzufügen von doppelten Schlüsseln zu einem Javascript-Array verhindert

Ich beginne mit einem leeren Array und dann Schlüssel hinzufügen, wie die Seite mit jQuery geschrubbt wird.

Anfangs hoffte ich, dass etwas Einfaches wie die folgenden funktionieren würde: (unter Verwendung von Gattungsnamen)

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

No go. Gefolgt es mit:

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

auch versucht:

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

Nichts von alldem gearbeitet hat. Entweder wird nichts in das Array geschoben oder was ich versuche ist nicht besser als einfach zu erklären array[key] = value Warum ist etwas so einfach so schwer zu tun. Irgendwelche Ideen, damit das funktioniert?

+3

Sie versuchen auf 'Array' oder' Object'? – thecodeparadox

+0

ES6 hat jetzt [Set] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) native – Efren

Antwort

32

Im Allgemeinen ist dies besser erfüllt mit einem Objekt statt, da JavaScript nicht wirklich assoziative Arrays haben:

var foo = { bar: 0 }; 

Dann in verwenden für einen Schlüssel zu überprüfen:

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

Wie war in den Kommentaren zu Recht hingewiesen, ist diese Methode nützlich nur, wenn Ihre Schlüssel Strings sein werden, oder Elemente, die als Strings (wie Zahlen) dargestellt werden können.

+2

... unter der Annahme, dass Ihre Werte Zeichenfolgen oder als eindeutige Zeichenfolgen darstellbar sind (Dies beinhaltet Zahlen). – Phrogz

+0

@Phrogz Absolut. Gute Beratung für das OP. – Sampson

+3

Danke Jonathan. Das Licht hat endlich geklickt, was ich falsch gemacht habe. Ich wollte gerade sagen, dass deine Antwort auch nicht geholfen hat, aber nach etwas mehr Detektivarbeit freue ich mich, sagen zu können, dass es perfekt funktioniert hat. Und danke für die Tipps zu Objects. Ich werde das im Hinterkopf behalten. – 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] 

Weitere Details zu Array.indexOf nachlesen.

Wenn Sie auf jQuery verlassen möchten, verwenden Sie stattdessen jQuery.inArray:

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

Wenn alle Ihre Werte sind einfach und eindeutig darstellbar als Strings jedoch sollten Sie ein Objekt anstelle eines Arrays verwenden, für eine potenziell massive Geschwindigkeitssteigerung (wie in der Antwort von @ JonathanSampson beschrieben).

+0

Auch das Problem mit 'indexOf' ist, dass es selbst eine Schleife macht ... Dies macht einen [Schlemiel der Maler-Algorithmus] (http://en.wikichip.org/wiki/Schlemiel_the_Painter_Algorithm), der verlangsamt mit jedem Element, das dem Array hinzugefügt wurde. –

0

Die Logik ist falsch. Bedenken Sie:

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 

Es gibt keinen Grund zur Schleife ist für Schlüssel (oder Indizes für Arrays) Existenz zu überprüfen. Jetzt, Werte sind eine andere Geschichte ...

Glücklich Codierung

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

Ausgang:

getting repeated 
true