it-swarm.it

Trova oggetto per id in una matrice 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'oggetto nell'array. 

Come posso farlo in JavaScript o usando jQuery?

1246
thugsb

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 invece vuoi trovare il suo index, 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 vuoi ottenere un array di elementi corrispondenti, usa invece il metodo filter() :

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

Ciò restituirà una matrice di oggetti. Se vuoi ottenere una matrice 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 funzioni arrow 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 ).

677

Poiché stai già utilizzando jQuery, puoi utilizzare 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'oggetto è sempre lì e che si verifica solo una volta, puoi semplicemente usare 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
}
1430
Guffa

Un'altra soluzione è creare un oggetto 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.

347
Aaron Digulla

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

Funziona senza librerie esterne. Ma se vuoi il vecchio supporto per il browser potresti voler includere questo polyfill .

158
Rúnar Berg

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' })
140
GijsjanB

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
123
pimvdb

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;
}
65
JaredPar
myArray.filter(function(a){ return a.id == some_id_you_want })[0]
42
Danilo Colasso

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');
30
will Farrell

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/

14
hunter

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);
13
Joe Lewis

Mentre ci sono 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 oggetto come ricerca: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map

10
Tom

Utilizzando nativo 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

10
laggingreflex

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. Restituisce 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'
6
Dan W

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
4
mr.musicman

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 oggetto con più proprietà ad esso per aggiungere un altro "where-clause".

Nota che Sugarjs estende gli oggetti nativi, e alcune persone considerano questo molto cattivo ...

4
deepflame

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
4
Jonas Wilms

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;
    });
}
3
Sumit Ridhal

Iterare su qualsiasi elemento dell'array. Per ogni oggetto che visiti, controlla l'id dell'oggetto. 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];
}
3
Zirak

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 di key e "45" al posto di value, e otterrai l'oggetto completo che corrisponde a un id di 45. Quindi sarebbe,

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

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

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

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

2
quincyaft

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 proprio come $.grep e se un oggetto viene scoperto, function restituirà l'oggetto, piuttosto che un array.

1
soytian

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 oggetto con id.

1
volumexxx

Considera "axesOptions" come array di oggetti con un formato oggetto {: 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;
}
0
ramya

Più generico e breve

function findFromArray(array,key,value) {
        return array.filter(function (element) {
            return element[key] == value;
        }).shift();
}

nel tuo caso Ex. var element = findFromArray(myArray,'id',45) che ti darà l'intero elemento.

0
Savan Kaneriya

Più breve,

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

Possiamo usare i metodi di Jquery $ .each ()/$. Grep () var data= []; $.each(array,function(i){if(n !== 5 && i > 4){data.Push(item)}}

var data = $.grep(array, function( n, i ) { return ( n !== 5 && i > 4 ); });

utilizzare la sintassi ES6: Array.find, Array.filter, Array.forEach, Array.map

Oppure usa Lodash https://lodash.com/docs/4.17.10#filter , Underscore https://underscorejs.org/#filter

0
TLbiz

A partire da la risposta di aggaton , questa è una funzione che restituisce effettivamente l'elemento voluto (o null se non trovato), dato il array e una funzione 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-, in quanto non supporta some. Un polyfill può essere fornito, in alternativa c'è sempre il classico ciclo for:

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.

0
MaxArt