Zoek object op id in een array van JavaScript-objecten

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 45doorgegeven 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 wordt undefinedgeretourneerd.


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].foogebruiken 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 traditionele for(E)
  • verrassend genoeg in Firefox voor kleine arrays-oplossing op basis van Map(K) is langzamer dan traditionele for(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) en findIndex(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 keyen “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 $.grepen 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”.

Other episodes