Trova l’object per id in una serie di oggetti JavaScript

Ho una matrice:

myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}, etc.] 

Non riesco a cambiare la struttura dell’array. Mi viene passato un id di 45 e voglio ottenere 'bar' per quell’object nell’array.

Come posso farlo in JavaScript o usando jQuery?

Usa il metodo find() :

 myArray.find(x => x.id === '45').foo; 

Da MDN :

Il metodo find() restituisce un valore nella matrice, se un elemento dell’array soddisfa la funzione di test fornita. Altrimenti viene restituito undefined .


Se vuoi invece trovare il suo indice , usa findIndex() :

 myArray.findIndex(x => x.id === '45'); 

Da MDN :

Il metodo findIndex() restituisce l’indice del primo elemento dell’array che soddisfa la funzione di test fornita. Altrimenti viene restituito -1.


Se si desidera ottenere una matrice di elementi corrispondenti, utilizzare invece il metodo filter() :

 myArray.filter(x => x.id === '45'); 

Ciò restituirà una matrice di oggetti. Se vuoi ottenere una serie di proprietà foo , puoi farlo con il metodo map() :

 myArray.filter(x => x.id === '45').map(x => x.foo); 

Nota a margine: metodi come find() o filter() e le funzioni freccia non sono supportati dai browser più vecchi (come IE), quindi se vuoi supportare questi browser, devi trascrivere il tuo codice usando Babel (con il polyfill ).

Dato che stai già usando jQuery, puoi usare la funzione grep che è intesa per la ricerca di un array:

 var result = $.grep(myArray, function(e){ return e.id == id; }); 

Il risultato è un array con gli elementi trovati. Se sai che l’object è sempre lì e che si verifica solo una volta, puoi usare il result[0].foo per ottenere il valore. Altrimenti dovresti controllare la lunghezza dell’array risultante. Esempio:

 if (result.length == 0) { // not found } else if (result.length == 1) { // access the foo property using result[0].foo } else { // multiple items found } 

Un’altra soluzione è creare un object lookup:

 var lookup = {}; for (var i = 0, len = array.length; i < len; i++) { lookup[array[i].id] = array[i]; } ... now you can use lookup[id]... 

Questo è particolarmente interessante se hai bisogno di fare molte ricerche.

Ciò non richiederà molta più memoria poiché gli ID e gli oggetti saranno condivisi.

ECMAScript 2015 fornisce il metodo find () sugli array:

 var myArray = [ {id:1, name:"bob"}, {id:2, name:"dan"}, {id:3, name:"barb"}, ] // grab the Array item which matchs the id "2" var item = myArray.find(item => item.id === 2); // print console.log(item.name); 

Underscore.js ha un buon metodo per questo:

 myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.] obj = _.find(myArray, function(obj) { return obj.id == '45' }) 

Penso che il modo più semplice sarebbe il seguente, ma non funzionerà su Internet Explorer 8 (o versioni precedenti):

 var result = myArray.filter(function(v) { return v.id === '45'; // Filter out the appropriate one })[0].foo; // Get result and access the foo property 

Prova quanto segue

 function findById(source, id) { for (var i = 0; i < source.length; i++) { if (source[i].id === id) { return source[i]; } } throw "Couldn't find object with id: " + id; } 
 myArray.filter(function(a){ return a.id == some_id_you_want })[0] 

Una versione generica e più flessibile della funzione findById sopra:

 // array = [{key:value},{key:value}] function objectFindByKey(array, key, value) { for (var i = 0; i < array.length; i++) { if (array[i][key] === value) { return array[i]; } } return null; } var array = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}]; var result_obj = objectFindByKey(array, 'id', '45'); 

Puoi usare i filtri,

  function getById(id, myArray) { return myArray.filter(function(obj) { if(obj.id == id) { return obj } })[0] } get_my_obj = getById(73, myArray); 

Puoi ottenerlo facilmente usando la funzione map () :

 myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}]; var found = $.map(myArray, function(val) { return val.id == 45 ? val.foo : null; }); //found[0] == "bar"; 

Esempio di lavoro: http://jsfiddle.net/hunter/Pxaua/

Utilizzando l’ Array.reduce

 var array = [ {'id':'73' ,'foo':'bar'} , {'id':'45' ,'foo':'bar'} , ]; var id = 73; 
 var found = array.reduce(function(a, b){ return (a.id==id && a) || (b.id == id && b) }); 

restituisce l’elemento object se trovato, altrimenti false

Sebbene ci siano molte risposte corrette qui, molte di esse non affrontano il fatto che si tratta di un’operazione inutilmente costosa se fatta più di una volta. In un caso estremo, questa potrebbe essere la causa di reali problemi di prestazioni.

Nel mondo reale, se si elaborano molti articoli e le prestazioni sono un problema, è molto più veloce inizialmente creare una ricerca:

 var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}]; var lookup = items.reduce((o,i)=>o[i.id]=o,{}); 

puoi quindi ottenere elementi in orari prestabiliti come questo:

 var bar = o[id]; 

Potresti anche considerare l’utilizzo di una mappa anziché di un object come ricerca: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map

Puoi provare Sugarjs da http://sugarjs.com/ .

Ha un metodo molto dolce su Array .find Quindi puoi trovare un elemento come questo:

 array.find( {id: 75} ); 

Puoi anche passare un object con più proprietà ad esso per aggiungere un altro “where-clause”.

Nota che Sugarjs estende gli oggetti nativi e alcune persone considerano questo molto malvagio …

Basandosi sulla risposta accettata:

jQuery:

 var foo = $.grep(myArray, function(e){ return e.id === foo_id}) myArray.pop(foo) 

O CoffeeScript:

 foo = $.grep myArray, (e) -> e.id == foo_id myArray.pop foo 

Ecco come farei su di esso in puro JavaScript, nel modo più minimale che riesco a pensare che funzioni in ECMAScript 3 o versioni successive. Ritorna non appena viene trovata una corrispondenza.

 var getKeyValueById = function(array, key, id) { var testArray = array.slice(), test; while(test = testArray.pop()) { if (test.id === id) { return test[key]; } } // return undefined if no matching id is found in array return; } var myArray = [{'id':'73', 'foo':'bar'}, {'id':'45', 'foo':'bar'}] var result = getKeyValueById(myArray, 'foo', '45'); // result is 'bar', obtained from object with id of '45' 

Se lo fai più volte, puoi impostare una mappa (ES6):

 const map = new Map( myArray.map(el => [el.id, el]) ); 

Quindi puoi semplicemente fare:

 map.get(27).foo 

Puoi farlo anche in puro JavaScript usando la funzione “filtro” integrata per gli array:

 Array.prototype.filterObjects = function(key, value) { return this.filter(function(x) { return x[key] === value; }) } 

Quindi ora passa semplicemente “id” al posto della key e “45” al posto del value , e otterrai l’object completo che corrisponde a un id di 45. Così sarebbe,

 myArr.filterObjects("id", "45"); 

Mi è piaciuta molto la risposta fornita da Aaron Digulla ma avevo bisogno di mantenere la mia gamma di oggetti in modo da poterlo scorrere in seguito. Quindi l’ho modificato in

  var indexer = {}; for (var i = 0; i < array.length; i++) { indexer[array[i].id] = parseInt(i); } //Then you can access object properties in your array using array[indexer[id]].property 

Iterate su qualsiasi elemento dell’array. Per ogni object che visiti, controlla l’id dell’object. Se è una partita, restituiscila.

Se vuoi solo il codicez:

 function getId(array, id) { for (var i = 0, len = array.length; i < len; i++) { if (array[i].id === id) { return array[i]; } } return null; // Nothing found } 

E la stessa cosa con i metodi Array di ECMAScript 5:

 function getId(array, id) { var obj = array.filter(function (val) { return val.id === id; }); // Filter returns an array, and we just want the matching item. return obj[0]; } 

Finché il browser supporta ECMA-262 , 5a edizione (dicembre 2009), questo dovrebbe funzionare, quasi un solo liner:

 var bFound = myArray.some(function (obj) { return obj.id === 45; }); 

Usa la funzione Array.prototype.filter() .

DEMO : https://jsfiddle.net/sumitridhal/r0cz0w5o/4/

JSON

 var jsonObj =[ { "name": "Me", "info": { "age": "15", "favColor": "Green", "pets": true } }, { "name": "Alex", "info": { "age": "16", "favColor": "orange", "pets": false } }, { "name": "Kyle", "info": { "age": "15", "favColor": "Blue", "pets": false } } ]; 

FILTRO

 var getPerson = function(name){ return jsonObj.filter(function(obj) { return obj.name === name; }); } 

Uso:

 var retObj ={}; $.each(ArrayOfObjects, function (index, obj) { if (obj.id === '5') { // id.toString() if it is int retObj = obj; return false; } }); return retObj; 

Dovrebbe restituire un object con id.

Questa soluzione può anche essere utile:

 Array.prototype.grep = function (key, value) { var that = this, ret = []; this.forEach(function (elem, index) { if (elem[key] === value) { ret.push(that[index]); } }); return ret.length < 2 ? ret[0] : ret; }; var bar = myArray.grep("id","45"); 

L'ho fatto come $.grep e se un object viene scoperto, la funzione restituirà l'object, piuttosto che un array.

A partire dalla risposta di aggaton , questa è una funzione che restituisce effettivamente l’elemento desiderato (o null se non trovato), dato l’ array e una funzione di callback che restituisce un valore di verità per l’elemento “corretto”:

 function findElement(array, callback) { var elem; return array.some(function(e) { if (callback(e)) { elem = e; return true; } }) ? elem : null; }); 

Ricorda che questo non funziona in modo nativo su IE8, poiché non ne supporta some . Un polyfill può essere fornito, in alternativa c’è sempre il classico for loop:

 function findElement(array, callback) { for (var i = 0; i < array.length; i++) if (callback(array[i])) return array[i]; return null; }); 

In realtà è più veloce e più compatto. Ma se non vuoi reinventare la ruota, ti suggerisco di usare una libreria di utilità come underscore o lodash.

Più breve,

 var theAnswerObj = _.findWhere(array, {id : 42}); 

Considera “axesOptions” come array di oggetti con un formato object {{field_type => 2,: fields => [1,3,4]}

 function getFieldOptions(axesOptions,choice){ var fields=[] axesOptions.each(function(item){ if(item.field_type == choice) fields= hashToArray(item.fields) }); return fields; } 

Utilizza il metodo di filtro di jQuery:

  $(myArray).filter(function() { return this.id == desiredId; }).first(); 

Ciò restituirà il primo elemento con l’Id specificato.

Ha anche il vantaggio di un bel formato C # LINQ.