Trouver l'objet par id dans un tableau d'objets JavaScript
j'ai un tableau:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}, etc.]
Je ne peux pas changer la structure du tableau. On me passe un id de 45
, et je veux avoir 'bar'
pour cet objet dans le tableau.
Comment faire en JavaScript ou en utilisant jQuery?
29 réponses
utiliser la méthode find()
:
myArray.find(x => x.id === '45').foo;
à Partir de MDN :
la méthode
find()
renvoie une valeur dans le tableau, si un élément dans le tableau satisfait à la fonction de test fournie. Sinon,undefined
est retourné.
si vous voulez trouver son index instead, use findIndex()
:
myArray.findIndex(x => x.id === '45');
à Partir de MDN :
la méthode
findIndex()
retourne l'index du premier élément du tableau qui satisfait la fonction de test fournie. Sinon -1 est retourné.
si vous voulez obtenir un tableau d'éléments correspondants, utilisez la filter()
méthode à la place:
myArray.filter(x => x.id === '45');
ceci retournera un tableau d'objets. Si vous voulez obtenir un tableau de propriétés foo
, vous pouvez le faire avec la map()
méthode:
myArray.filter(x => x.id === '45').map(x => x.foo);
Side note: des méthodes comme find()
ou filter()
, et fonctions de flèche ne sont pas pris en charge par des navigateurs plus anciens (comme IE), donc si vous voulez prendre en charge ces navigateurs, vous devez transpirer votre code en utilisant Babel (avec le polyfill ).
comme vous utilisez déjà jQuery, vous pouvez utiliser la fonction grep qui est destiné à la recherche d'un tableau:
var result = $.grep(myArray, function(e){ return e.id == id; });
Le résultat est un tableau avec les éléments trouvés. Si vous savez que l'objet est toujours là et qu'il se produit seulement une fois, vous pouvez simplement utiliser result[0].foo
pour obtenir la valeur. Sinon, vous devriez vérifier la longueur du tableau résultant. Exemple:
if (result.length == 0) {
// not found
} else if (result.length == 1) {
// access the foo property using result[0].foo
} else {
// multiple items found
}
une autre solution consiste à créer un objet de recherche:
var lookup = {};
for (var i = 0, len = array.length; i < len; i++) {
lookup[array[i].id] = array[i];
}
... now you can use lookup[id]...
c'est particulièrement intéressant si vous avez besoin de faire de nombreuses recherches.
cela n'aura pas besoin de beaucoup plus de mémoire puisque les ID et les objets seront partagés.
ECMAScript 2015 assure le find() méthode des tableaux:
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);
fonctionne sans bibliothèques externes. Mais si vous voulez soutien de navigateur plus ancien vous pourriez vouloir inclure ce polyfill .
trait de Soulignement.js a une belle méthode pour cela:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.]
obj = _.find(myArray, function(obj) { return obj.id == '45' })
je pense que la façon la plus facile serait la suivante, mais elle ne fonctionnera pas sur Internet Explorer 8 (ou plus tôt):
var result = myArray.filter(function(v) {
return v.id === '45'; // Filter out the appropriate one
})[0].foo; // Get result and access the foo property
essayez ce qui suit
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]
une version générique et plus flexible de la fonction findById ci-dessus:
// 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');
vous pouvez utiliser des filtres,
function getById(id, myArray) {
return myArray.filter(function(obj) {
if(obj.id == id) {
return obj
}
})[0]
}
get_my_obj = getById(73, myArray);
vous pouvez obtenir ce facilement en utilisant le map () fonction:
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";
exemple pratique: http://jsfiddle.net/hunter/Pxaua /
en utilisant natif 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)
});
renvoie l'élément objet s'il est trouvé, sinon false
bien qu'il y ait beaucoup de bonnes réponses ici, beaucoup d'entre elles ne tiennent pas compte du fait qu'il s'agit d'une opération inutilement coûteuse si elle est effectuée plus d'une fois. Dans un cas extrême, cela pourrait être la cause de réels problèmes de performance.
dans le monde réel, si vous êtes en train de traiter beaucoup d'articles et que la performance est une préoccupation, il est beaucoup plus rapide de commencer à construire une recherche:
var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
var lookup = items.reduce((o,i)=>o[i.id]=o,{});
vous pouvez alors obtenir des articles à temps fixe comme ceci :
var bar = o[id];
vous pourriez également envisager d'utiliser une carte au lieu d'un objet comme la recherche: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map
vous pouvez essayer Sugarjs de http://sugarjs.com / .
il a une méthode très douce sur les tableaux, .find
. Donc vous pouvez trouver un élément comme ceci:
array.find( {id: 75} );
vous pouvez également passer un objet avec plus de propriétés pour y ajouter une autre"clause où".
notez que Sugarjs étend des objets indigènes, et certains considèrent cela très mal...
construire sur la réponse acceptée:
jQuery:
var foo = $.grep(myArray, function(e){ return e.id === foo_id})
myArray.pop(foo)
Or CoffeeScript:
foo = $.grep myArray, (e) -> e.id == foo_id
myArray.pop foo
Voici comment je m'y prendrais en JavaScript pur, de la manière la plus minimale que je puisse penser que cela fonctionne en ECMAScript 3 ou plus tard. Il renvoie dès qu'une correspondance est trouvée.
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'
si vous le faites plusieurs fois, vous pouvez configurer une carte (ES6):
const map = new Map( myArray.map(el => [el.id, el]) );
alors vous pouvez simplement faire:
map.get(27).foo
vous pouvez le faire même en JavaScript pur en utilisant la fonction "filter" intégrée pour les tableaux:
Array.prototype.filterObjects = function(key, value) {
return this.filter(function(x) { return x[key] === value; })
}
donc maintenant , il suffit de passer" id "à la place de key
et" 45 "à la place de value
, et vous obtiendrez l'objet complet correspondant à un id de 45. Donc, ce serait,
myArr.filterObjects("id", "45");
j'ai vraiment aimé la réponse fournie par Aaron Digulla mais j'avais besoin de garder mon tableau d'objets pour que je puisse itérer à travers elle plus tard. Alors je l'ai modifié en
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
Itérer sur n'importe quel élément dans le tableau. Pour chaque article que vous visitez, Vérifiez l'identité de cet article. Si c'est un match retour.
Si vous voulez juste teh codez:
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
}
et la même chose en utilisant les méthodes du tableau D'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];
}
Utiliser Array.prototype.filter()
de la fonction.
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
}
}
];
filtre
var getPerson = function(name){
return jsonObj.filter(function(obj) {
return obj.name === name;
});
}
utiliser:
var retObj ={};
$.each(ArrayOfObjects, function (index, obj) {
if (obj.id === '5') { // id.toString() if it is int
retObj = obj;
return false;
}
});
return retObj;
Il doit retourner un objet par id.
Cette solution peut aider:
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");
je l'ai fait tout comme $.grep
et si un seul objet est de trouver, fonction sera de retour l'objet, plutôt qu'un tableau.
à partir de réponse d'aggaton , il s'agit d'une fonction qui retourne en fait l'élément désiré (ou null
si non trouvé), étant donné la array
et une callback
fonction qui renvoie une valeur vraie pour l'élément "correct":
function findElement(array, callback) {
var elem;
return array.some(function(e) {
if (callback(e)) {
elem = e;
return true;
}
}) ? elem : null;
});
juste se rappeler que cela ne fonctionne pas nativement sur IE8-, car il ne supporte pas some
. Un polyfill peut être fourni, alternativement il y a toujours la boucle classique for
:
function findElement(array, callback) {
for (var i = 0; i < array.length; i++)
if (callback(array[i])) return array[i];
return null;
});
c'est en fait plus rapide et plus compact. Mais si vous ne voulez pas réinventer la roue, je suggère d'utiliser une bibliothèque utilitaire comme underscore ou lodash.
le plus court", 151920920"
var theAnswerObj = _.findWhere(array, {id : 42});
prendre en considération "axesOptions" d'être ensemble d'objets avec un format de l'objet en cours {:type_champ => 2, :champs => [1,3,4]}
function getFieldOptions(axesOptions,choice){
var fields=[]
axesOptions.each(function(item){
if(item.field_type == choice)
fields= hashToArray(item.fields)
});
return fields;
}
nous pouvons utiliser des méthodes Jquery $.chacun.$/)(grep()
var data= [];
$.each(array,function(i){if(n !== 5 && i > 4){data.push(item)}}
ou
var data = $.grep(array, function( n, i ) {
return ( n !== 5 && i > 4 );
});
utiliser la syntaxe ES6:
Array.find, Array.filter, Array.forEach, Array.map
ou utiliser Lodash https://lodash.com/docs/4.17.10#filter , Underscore https://underscorejs.org/#filter
utiliser la méthode du filtre de jQuery:
$(myArray).filter(function()
{
return this.id == desiredId;
}).first();
qui renvoie le premier élément avec L'Id spécifié.
il a également l'avantage d'un format agréable c# LINQ looking.