Ik heb een array:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}, etc.]
Ik kan de structuur van de array niet wijzigen. Ik krijg een ID van 45
doorgegeven en ik wil 'bar'
voor dat object in de array krijgen.
Hoe doe ik dit in JavaScript of met jQuery?
Antwoord 1, autoriteit 100%
Gebruik de find()
methode:
myArray.find(x => x.id === '45').foo;
Van MDN:
De methode
find()
retourneert de eerste waarde in de array, als een element in de array voldoet aan de opgegeven testfunctie. Anders wordtundefined
geretourneerd.
Als je in plaats daarvan de indexwilt vinden, gebruik dan findIndex()
:
myArray.findIndex(x => x.id === '45');
Van MDN:
De methode
findIndex()
retourneert de index van het eerste element in de array dat voldoet aan de opgegeven testfunctie. Anders wordt -1 geretourneerd.
Als u een reeks overeenkomende elementen wilt krijgen, gebruikt u de filter()
methode in plaats daarvan:
myArray.filter(x => x.id === '45');
Hiermee wordt een array met objecten geretourneerd. Als u een reeks foo
-eigenschappen wilt krijgen, kunt u dit doen met de map()
methode:
myArray.filter(x => x.id === '45').map(x => x.foo);
Kanttekening: methoden zoals find()
of filter()
en pijlfunctiesworden niet ondersteund door oudere browsers (zoals IE), dus als u deze browsers wilt ondersteunen, moet u uw code transpileren met Babel(met de polyfill).
Antwoord 2, autoriteit 89%
Omdat u jQuery al gebruikt, kunt u de functie grepgebruiken die bedoeld is voor zoeken in een array:
var result = $.grep(myArray, function(e){ return e.id == id; });
Het resultaat is een array met de gevonden items. Als je weet dat het object er altijd is en dat het maar één keer voorkomt, kun je gewoon result[0].foo
gebruiken om de waarde te krijgen. Anders moet u de lengte van de resulterende array controleren. Voorbeeld:
if (result.length === 0) {
// no result found
} else if (result.length === 1) {
// property found, access the foo property using result[0].foo
} else {
// multiple items found
}
Antwoord 3, autoriteit 22%
Een andere oplossing is om een opzoekobject te maken:
var lookup = {};
for (var i = 0, len = array.length; i < len; i++) {
lookup[array[i].id] = array[i];
}
... now you can use lookup[id]...
Dit is vooral interessant als je veel opzoekingen moet doen.
Dit heeft niet veel meer geheugen nodig omdat de ID’s en objecten worden gedeeld.
Antwoord 4, autoriteit 12%
ECMAScript 2015(JavaScript ES6) biedt de find()
methode op arrays:
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);
Antwoord 5, autoriteit 9%
Underscore.jsheeft daar een mooie methode voor:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.]
obj = _.find(myArray, function(obj) { return obj.id == '45' })
Antwoord 6, autoriteit 8%
Ik denk dat de gemakkelijkste manier de volgende is, maar het werkt niet op Internet Explorer 8 (of eerder):
var result = myArray.filter(function(v) {
return v.id === '45'; // Filter out the appropriate one
})[0].foo; // Get result and access the foo property
Antwoord 7, Autoriteit 5%
Probeer het volgende
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;
}
Antwoord 8, Autoriteit 3%
myArray.filter(function(a){ return a.id == some_id_you_want })[0]
Antwoord 9, Autoriteit 2%
Een generieke en flexibelere versie van de FindByID-functie hierboven:
// 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');
Antwoord 10
Prestaties
Vandaag 2020.06.20 Ik voer test op MacOS High Sierra op Chrome 81.0, Firefox 77.0 en Safari 13.1 voor gekozen oplossingen.
Conclusies voor oplossingen die precalculaties gebruiken
Oplossingen met precalculaties (K, L) zijn (veel) sneller dan andere oplossingen en zullen niet met hen worden vergeleken – waarschijnlijk gebruiken ze een speciale ingebouwde browseroptimalisaties
- verrassend genoeg zijn Chrome- en Safari-oplossingen op basis van
Map
(K) veel sneller dan oplossingen op basis van object{}
(L) - verrassend genoeg in Safari voor kleine arrays-oplossing op basis van object
{}
(L) is langzamer dan traditionelefor
(E) - verrassend genoeg in Firefox voor kleine arrays-oplossing op basis van
Map
(K) is langzamer dan traditionelefor
(E)
Conclusies wanneer gezochte objecten ALTIJD bestaan
- oplossing die traditionele
for
(E) gebruikt, is het snelst voor kleine arrays en snel voor grote arrays - oplossing met cache (J) is het snelst voor grote arrays – verrassend genoeg is het voor kleine arrays gemiddeld snel
- oplossingen op basis van
find
(A) enfindIndex
(B) zijn snel voor kleine arrays en gemiddeld snel voor grote arrays - oplossing gebaseerd op
$.map
(H) is het langzaamst op kleine arrays - oplossing gebaseerd op
reduce
(D) is het langzaamst op grote arrays
Conclusies wanneer gezochte objecten NOOIT bestaan
- oplossing gebaseerd op traditionele
for
(E) is het snelst op kleine en grote arrays (behalve Chrome-small arrays waar het op de tweede plaats komt) - oplossing gebaseerd op
reduce
(D) is het langzaamst op grote arrays - oplossing die cache (J) gebruikt, is gemiddeld snel, maar kan worden versneld als we in de cache ook sleutels opslaan die null-waarden hebben (wat hier niet is gedaan omdat we onbeperkt geheugengebruik in de cache willen vermijden in het geval dat veel niet bestaande sleutels worden doorzocht)
Details
voor oplossingen
- zonder precalculaties: a
b
C
D
e
f
G
h
i
J (de J Oplossing-gebruik ‘Innerlijke’ cache en IT-snelheid is afhankelijk van hoe vaak gezochte elementen zullen herhalen) - met precalculaties
k
l
Ik voer vier tests uit. In tests wil ik 5 objecten vinden in 10 lus-iteraties (de objecten-ID niet veranderen tijdens iteraties) – dus ik geef 50 keer geteste methode, maar slechts de eerste 5 keer hebben unieke ID-waarden:
- Kleine array (10 elementen) en gezochteobject bestaat altijd – u kunt het uitvoeren hier
- Big Array (10K-elementen) en altijd gezocht bestaan altijd – u kunt het uitvoeren hier
- Kleine array (10 elementen) en gezochte object bestaat nooit – u kunt het uitvoeren hier
- grote array (10k elementen) en gezocht object bestaat NOOIT – u kunt het HIER
Geteste codes worden hieronder weergegeven
Antwoord 11
U kunt dit eenvoudig verkrijgen met de functie 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";
Werkvoorbeeld: http://jsfiddle.net/hunter/Pxaua/
Antwoord 12
U kunt filters gebruiken,
function getById(id, myArray) {
return myArray.filter(function(obj) {
if(obj.id == id) {
return obj
}
})[0]
}
get_my_obj = getById(73, myArray);
Antwoord 13
Native 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)
});
retourneert het objectelement indien gevonden, anders false
Antwoord 14
Hoewel er hier veel juiste antwoorden zijn, gaan veel ervan niet in op het feit dat dit een onnodig dure operatie is als het meer dan eens wordt gedaan. In een extreem geval kan dit de oorzaak zijn van echte prestatieproblemen.
In de echte wereld, als je veel items verwerkt en prestaties een probleem zijn, is het veel sneller om in eerste instantie een zoekopdracht op te bouwen:
var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
var lookup = items.reduce((o,i)=>o[i.id]=o,{});
je kunt dan op een vaste tijd als volgt bij items komen:
var bar = o[id];
U kunt ook overwegen een kaart te gebruiken in plaats van een object als zoekactie: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map
Antwoord 15
Als je dit meerdere keren doet, kun je een kaart (ES6) instellen:
const map = new Map( myArray.map(el => [el.id, el]) );
Dan kunt u eenvoudig een O(1)-zoekopdracht uitvoeren:
map.get(27).foo
Antwoord 16
Onlangs heb ik met hetzelfde te maken gehad waarbij ik de string moet doorzoeken vanuit een enorme array.
Na wat zoeken vond ik Het zal gemakkelijk te hanteren zijn met eenvoudige code:
Code:
var items = mydata.filter(function(item){
return item.word.toLowerCase().startsWith( 'gk );
})
Zie https://jsfiddle.net/maheshwaghmare/cfx3p40v/4/
Antwoord 17
Zolang de browser ECMA-262ondersteunt, 5e editie (december 2009) , dit zou moeten werken, bijna one-liner:
var bFound = myArray.some(function (obj) {
return obj.id === 45;
});
Antwoord 18
Hier is hoe ik het zou aanpakken in puur JavaScript, op de meest minimale manier die ik kan bedenken die werkt in ECMAScript 3 of later. Het keert terug zodra er een match is gevonden.
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'
Antwoord 19
Algemeen en kort
function findFromArray(array,key,value) {
return array.filter(function (element) {
return element[key] == value;
}).shift();
}
in uw geval Ex. var element = findFromArray(myArray,'id',45)
waarmee je het hele element krijgt.
Antwoord 20
Itereer een willekeurig item in de array. Controleer voor elk item dat u bezoekt de ID van dat item. Als het een match is, stuur het dan terug.
Als je alleen de codez wilt:
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
}
En hetzelfde met de Array-methoden van 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];
}
Antwoord 21
Je kunt Sugarjs uitproberen via http://sugarjs.com/.
Het heeft een erg leuke methode op Arrays, .find
. Dus je kunt een element als dit vinden:
array.find( {id: 75} );
U kunt ook een object met meer eigenschappen doorgeven om een andere “waar-clausule” toe te voegen.
Merk op dat Sugarjs native objecten uitbreidt, en sommige mensen vinden dit erg slecht…
Antwoord 22
We kunnen JQuery-methoden gebruiken $.each()/$.grep()
var data= [];
$.each(array,function(i){if(n !== 5 && i > 4){data.push(item)}}
of
var data = $.grep(array, function( n, i ) {
return ( n !== 5 && i > 4 );
});
gebruik de ES6-syntaxis:
Array.find, Array.filter, Array.forEach, Array.map
of gebruik Lodash https://lodash.com/docs/4.17.10#Filter, underscore https://underscorejs.org/#filter
Antwoord 23
Zoals anderen hebben opgemerkt, .find()
is de manier om te gaan wanneer u op zoek bent naar een object in uw array. Als uw object echter niet kan worden gevonden met behulp van deze methode, crasht uw programma:
const myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
const res = myArray.find(x => x.id === '100').foo; // Uh oh!
/*
Error:
"Uncaught TypeError: Cannot read property 'foo' of undefined"
*/
Antwoord 24
Gebouw op het geaccepteerde antwoord:
jQuery:
var foo = $.grep(myArray, function(e){ return e.id === foo_id})
myArray.pop(foo)
of coffeescript:
foo = $.grep myArray, (e) -> e.id == foo_id
myArray.pop foo
Antwoord 25
Gebruik Array.prototype.filter()
functie.
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
}
}
];
FILTER
var getPerson = function(name){
return jsonObj.filter(function(obj) {
return obj.name === name;
});
}
Antwoord 26
U kunt dit zelfs in puur JavaScript doen door de ingebouwde “filter”-functie voor arrays te gebruiken:
Array.prototype.filterObjects = function(key, value) {
return this.filter(function(x) { return x[key] === value; })
}
Dus geef nu gewoon “id” door in plaats van key
en “45” in plaats van value
, en je krijgt het volledige object dat overeenkomt met een id van 45. Dus dat zou zijn,
myArr.filterObjects("id", "45");
Antwoord 27
Ik vond het antwoord van Aaron Digulla erg leuk, maar ik moest mijn reeks objecten bewaren, zodat ik het later kon herhalen. Dus ik heb het gewijzigd 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
Antwoord 28
Gebruik:
var retObj ={};
$.each(ArrayOfObjects, function (index, obj) {
if (obj.id === '5') { // id.toString() if it is int
retObj = obj;
return false;
}
});
return retObj;
Het zou een object op id moeten retourneren.
Antwoord 29
Deze oplossing kan ook nuttig zijn:
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");
Ik heb het gemaakt zoals $.grep
en als een object wordt gevonden, zal functionhet object retourneren in plaats van een array.
Antwoord 30
Dynamische gecachte vondst
Als we in deze oplossing naar een object zoeken, slaan we het op in de cache. Dit is het middelpunt tussen “altijd zoeken naar oplossingen” en “hash-map maken voor elk object in voorberekeningen”.