2011-12-29 9 views
7

Eventuali duplicati:
indexOf method in an object array?problemi con l'uso indexOf su una serie complessa

Ho un array JavaScript che segue questo formato:

var arrayName = [ 
{id: "a", gender: "man", item: "stuff"}, 
{id: "b", gender: "woman", item: "stuff"}, 
{id: "c", gender: "man", item: "stuff"}, 
{id: "d", gender: "man", item: "stuff"} 
]; 

Esiste un modo che Posso usare array.indexOf per trovare un indice nella matrice, quando ad esempio conosco la variabile "id".

Ad esempio, ho provato;

var position = arrayName.indexOf("b"); 
arrayName[position].gender = "man" 

Al momento sto usando;

for(var i=0; i<arrayName.length; i++) { 
    if(arrayName[i].id == "b"){ 
     arrayName[i].gender = "man"; 
    } 
} 

Questa seconda tecnica funziona, ma la matrice reale che sto usando dispone di 150 voci e 10 elementi in ogni voce in modo loop attraverso di essa tutto sembra molto dispendioso quando so che il "id" della voce Voglio modificare. indexOf sarebbe un approccio molto più pulito se riuscirò a farlo funzionare.

+2

Chiamare indexOf su un array non è compatibile con browser. – erturne

+0

@erturne - hai ragione - non è nemmeno in IE8 - wow –

+1

@erturne: non lo è, ma [come dichiarato su Mozilla Developer Network] (https://developer.mozilla.org/en/JavaScript/Reference/ Global_Objects/Array/indexOf), può essere facilmente implementato anche in browser obsoleti/deprecati. – Tadeck

risposta

18

La chiamata a indexOf sta controllando gli oggetti nell'array contro la stringa b, che non funzionerà mai.

Il ciclo degli elementi dell'array per trovare l'id corretto è una soluzione semplice.

Oppure, si potrebbe rendere il vostro propria funzione indexOf:

Array.prototype.indexOfId = function(id) { 
    for (var i = 0; i < this.length; i++) 
     if (this[i].id === id) 
      return i; 
    return -1; 
} 

    var arrayName = [ 
     { id: "a", gender: "man", item: "stuff" }, 
     { id: "b", gender: "woman", item: "stuff" }, 
     { id: "c", gender: "man", item: "stuff" }, 
     { id: "d", gender: "man", item: "stuff" }]; 

    var position = arrayName.indexOfId("b"); 

    alert(position); //alerts 1 

Ecco un fiddle

EDIT

Se si desidera confrontare gli elementi dell'array a qualsiasi proprietà, ecco come si fallo (nota che sto usando la sintassi [] per ottenere una proprietà arbitraria)

Array.prototype.indexOfField = function (propertyName, value) { 
     for (var i = 0; i < this.length; i++) 
      if (this[i][propertyName] === value) 
       return i; 
     return -1; 
    } 

    var position = arrayName.indexOfField("id", "b"); 
    alert(position); //alerts 1 

    position = arrayName.indexOfField("gender", "man"); 
    alert(position); //alerts 0 

Oppure, se non si vuole fare confusione con il prototipo di Array, e non ti dispiace utilizzando le funzionalità non presenti nei browser meno recenti, è possibile utilizzare la funzione di Array filter

var position = arrayName.indexOf(arrayName.filter(function (val) { 
     return val.id === "b"; 
})[0]); 

Si noti che questo funzione non è presente in IE8, e così di sostenere questo browser che avrebbe dovuto prendere il shim from MDN

EDIT - oops, indexOf non è amichevole verso vecchi browser sia.Se si opta per questa seconda parte di codice e ha voluto sostenere IE, devi anche avere per afferrare lo spessore per indexOf from here

+0

Grazie Adam, questo è quello che sospettavo. Probabilmente andrò avanti e utilizzerò una variante della tua tecnica prototype.indexOfId in quanto questi tipi di modifiche sono abbastanza comuni, quindi sarà più semplice fare riferimento a una singola funzione prototipo. La mia variante sarà probabilmente a: Array.prototype.indexOfId = function (variabile, valore) { per (var i = 0; i Nick

+0

@ user1121506 - che non funzionerà - stand by per un'altra modifica –

+0

@ user1121506 - modificato - il codice nel tuo commento era corretto al 99,9%, ti serviva solo un piccolo ritocco. –

0

è possibile sovrascrivere indexOf usando prototype

Array.prototype.indexOf = function(elem) { 
    for (var i = 0; i < this.length; i++){ 
     if (this[i].id === elem) 
      return i; 
    } 
    return -1; 
} 

var arrayName = [ 
{id: "a", gender: "man", item: "stuff"}, 
{id: "b", gender: "woman", item: "stuff"}, 
{id: "c", gender: "man", item: "stuff"}, 
{id: "d", gender: "man", item: "stuff"} 
]; 

alert(arrayName.indexOf("b")); 

violino: http://jsfiddle.net/r8rp9/1/

1

Se avete la possibilità, è possibile utilizzare per Array.prototype.filter:

var arrayName = [ 
    {id: "a", gender: "man", item: "stuff"}, 
    {id: "b", gender: "woman", item: "stuff"}, 
    {id: "c", gender: "man", item: "stuff"}, 
    {id: "d", gender: "man", item: "stuff"} 
]; 

console.log(arrayName.filter(function(i) { 
    return i.id === 'b'; 
})); 

che sarà g Iive:

[ { id: 'b', gender: 'woman', item: 'stuff' } ] 
+0

Cosa succede se voglio trovare l'indice e rimuovere l'elemento? –

+0

Semplicemente 'return i.id! == 'b';' invece. – NiKo

Problemi correlati