Odpowiedzi:
Użyj find()
metody:
myArray.find(x => x.id === '45').foo;
Z MDN :
find()
Sposób powraca do pierwszej wartości w tablicy, a element w tablicy spełnia podaną funkcję testowania. W przeciwnym razieundefined
jest zwracany.
Jeśli zamiast tego chcesz znaleźć jego indeks , użyj findIndex()
:
myArray.findIndex(x => x.id === '45');
Z MDN :
findIndex()
Metoda zwraca wskaźnik pierwszego elementu w tablicy, który spełnia podane funkcji testowych. W przeciwnym razie zwracane jest -1.
Jeśli chcesz uzyskać tablicę pasujących elementów, użyj filter()
metody:
myArray.filter(x => x.id === '45');
Zwróci to tablicę obiektów. Jeśli chcesz uzyskać tablicę foo
właściwości, możesz to zrobić za pomocą map()
metody:
myArray.filter(x => x.id === '45').map(x => x.foo);
Uwaga dodatkowa: metody takie jak find()
i filter()
oraz funkcje strzałek nie są obsługiwane przez starsze przeglądarki (takie jak IE), więc jeśli chcesz obsługiwać te przeglądarki, powinieneś przetłumaczyć swój kod za pomocą Babel (z polifill ).
Ponieważ już używasz jQuery, możesz użyć funkcji grep, która jest przeznaczona do przeszukiwania tablicy:
var result = $.grep(myArray, function(e){ return e.id == id; });
Wynikiem jest tablica ze znalezionymi elementami. Jeśli wiesz, że obiekt jest zawsze obecny i że występuje tylko raz, możesz użyć result[0].foo
tej wartości, aby uzyskać wartość. W przeciwnym razie powinieneś sprawdzić długość wynikowej tablicy. Przykład:
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
}
===
zamiast ==
, aby uniknąć dziwne problemy z JavaScript w ==
operatora.
e.id
i id
będzie struny, przypuszczam, że jest ok do użytku ==
. Ale jeśli nie jesteś pewien, możesz napotkać problemy (ponieważ '' == 0
jest, true
ale '' === 0
jest false
). Nie wspominając o tym, ===
że wydaje się być szybszy ( stackoverflow.com/questions/359494/… ).
===
ponieważ działa dokładnie tak , jak ==
w innych językach programowania. Uważam, że ==
JavaScript nie istnieje.
Innym rozwiązaniem jest utworzenie obiektu odnośnika:
var lookup = {};
for (var i = 0, len = array.length; i < len; i++) {
lookup[array[i].id] = array[i];
}
... now you can use lookup[id]...
Jest to szczególnie interesujące, jeśli musisz wykonać wiele wyszukiwań.
Nie będzie to wymagało więcej pamięci, ponieważ identyfikatory i obiekty będą udostępniane.
lookup
obiektu to strata czasu.
ECMAScript 2015 zapewnia metodę find () tablic:
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);
Działa bez bibliotek zewnętrznych. Ale jeśli chcesz obsługiwać starszą przeglądarkę, możesz dołączyć tę funkcję wypełniania .
myArray.find(d=>d.id===45).foo;
.
myArray.find(({ id }) => id === 45).foo
. Ale to stara odpowiedź, która została napisana, zanim składnia ES2015 była równie dobrze obsługiwana, jak teraz. @ Gothdo za odpowiedź jest obecnie najbardziej aktualne w wątku.
myArray.find(d => d.id === 45)?.foo
.
Underscore.js ma dobrą metodę:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.]
obj = _.find(myArray, function(obj) { return obj.id == '45' })
Myślę, że najprostszym sposobem byłoby, ale nie będzie działać w Internet Explorerze 8 (lub wcześniejszym):
var result = myArray.filter(function(v) {
return v.id === '45'; // Filter out the appropriate one
})[0].foo; // Get result and access the foo property
for
?
for
pętlą.
for
pętla kończy się przy pierwszym dopasowaniu.
id
Spróbuj wykonać następujące czynności
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]
Ogólna i bardziej elastyczna wersja powyższej funkcji findById:
// 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');
Możesz to łatwo uzyskać za pomocą funkcji 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";
Przykład roboczy: http://jsfiddle.net/hunter/Pxaua/
map
automatycznie usuwa null
elementy. Brzmi myląco dla mnie i dla wspólnej koncepcji map
, ponieważ wynik nie ma takiej samej długości oryginalnej kolekcji.
Możesz użyć filtrów,
function getById(id, myArray) {
return myArray.filter(function(obj) {
if(obj.id == id) {
return obj
}
})[0]
}
get_my_obj = getById(73, myArray);
Chociaż jest tutaj wiele poprawnych odpowiedzi, wiele z nich nie odnosi się do faktu, że jest to niepotrzebnie kosztowna operacja, jeśli jest wykonywana więcej niż jeden raz. W skrajnym przypadku może to być przyczyną rzeczywistych problemów z wydajnością.
W prawdziwym świecie, jeśli przetwarzasz wiele elementów, a problemem jest wydajność, znacznie szybciej jest początkowo zbudować wyszukiwanie:
var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
var lookup = items.reduce((o,i)=>o[i.id]=o,{});
następnie możesz dostać się na przedmioty w ustalonym czasie, takie jak to:
var bar = o[id];
Możesz również rozważyć użycie mapy zamiast obiektu jako odnośnika: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map
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)
});
zwraca element obiektu, jeśli zostanie znaleziony, w przeciwnym razie false
Jeśli zrobisz to wiele razy, możesz skonfigurować mapę (ES6):
const map = new Map( myArray.map(el => [el.id, el]) );
Następnie możesz po prostu zrobić:
map.get(27).foo
Oto jak poradzę sobie z tym w czystym JavaScript, w najbardziej minimalistyczny sposób, jaki mogę wymyślić, działa w ECMAScript 3 lub nowszym. Zwraca się, gdy tylko zostanie znalezione dopasowanie.
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'
Bardziej ogólny i krótki
function findFromArray(array,key,value) {
return array.filter(function (element) {
return element[key] == value;
}).shift();
}
w twoim przypadku np. var element = findFromArray(myArray,'id',45)
to da ci cały element.
Możesz wypróbować Sugarjs ze strony http://sugarjs.com/ .
Ma bardzo słodki sposób na tablicach, .find
. Możesz więc znaleźć element taki jak ten:
array.find( {id: 75} );
Możesz także przekazać obiekt o większej liczbie właściwości, aby dodać kolejną „klauzulę where”.
Zauważ, że Sugarjs rozszerza rodzime obiekty, a niektórzy uważają to za bardzo złe ...
find
. Moja sugestia jest taka, że jeśli chcesz rozszerzyć prototypy natywne, zawsze używaj bardziej szczegółowych nazw, pozostawiając najprostsze dla przyszłych standardowych rozwiązań.
Opierając się na przyjętej odpowiedzi:
jQuery:
var foo = $.grep(myArray, function(e){ return e.id === foo_id})
myArray.pop(foo)
Lub CoffeeScript:
foo = $.grep myArray, (e) -> e.id == foo_id
myArray.pop foo
Ostatnio muszę zmierzyć się z tym samym, w którym muszę przeszukać ciąg z ogromnej tablicy.
Po kilku poszukiwaniach znalazłem, że będzie to łatwe w obsłudze za pomocą prostego kodu:
Kod:
var items = mydata.filter(function(item){
return item.word.toLowerCase().startsWith( 'gk );
})
Iteruj po dowolnym elemencie w tablicy. Dla każdego odwiedzanego elementu sprawdź jego identyfikator. Jeśli pasuje, zwróć go.
Jeśli chcesz tylko kod:
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
}
I to samo przy użyciu metod macierzy 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];
}
Tak długo, jak przeglądarka obsługuje ECMA-262 , piąta edycja (grudzień 2009 r.), Powinno to działać prawie w jednym wierszu:
var bFound = myArray.some(function (obj) {
return obj.id === 45;
});
bFound
jest tylko wartością logiczną, która oznacza, true
że element spełnia wymagany warunek.
Możesz to zrobić nawet w czystym JavaScript, używając wbudowanej funkcji „filtrowania” tablic:
Array.prototype.filterObjects = function(key, value) {
return this.filter(function(x) { return x[key] === value; })
}
Teraz po prostu podaj „id” zamiast key
„45” zamiast value
, a otrzymasz pełny obiekt pasujący do identyfikatora 45. Tak więc,
myArr.filterObjects("id", "45");
Użyj Array.prototype.filter()
funkcji.
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
}
}
];
FILTR
var getPerson = function(name){
return jsonObj.filter(function(obj) {
return obj.name === name;
});
}
.filter
metody obj.info
w zagnieżdżonej pętli. var getPerson = function(name){ return jsonObj.filter(function(obj) { return obj.info.filter(function(info) { return pets === false; }); }); }
Możemy użyć metod Jquery $.each()/$.grep()
var data= [];
$.each(array,function(i){if(n !== 5 && i > 4){data.push(item)}}
lub
var data = $.grep(array, function( n, i ) {
return ( n !== 5 && i > 4 );
});
użyj składni ES6:
Array.find, Array.filter, Array.forEach, Array.map
Lub użyj Lodash https://lodash.com/docs/4.17.10#filter , Underscore https://underscorejs.org/#filter
Naprawdę podobała mi się odpowiedź udzielona przez Aarona Digullę, ale musiałem zachować mój zestaw obiektów, aby móc ją później iterować. Więc zmodyfikowałem to do
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
Posługiwać się:
var retObj ={};
$.each(ArrayOfObjects, function (index, obj) {
if (obj.id === '5') { // id.toString() if it is int
retObj = obj;
return false;
}
});
return retObj;
Powinien zwrócić obiekt według identyfikatora.
To rozwiązanie może być również pomocne:
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");
Zrobiłem to tak, $.grep
a jeśli jeden obiekt zostanie znaleziony, funkcja zwróci obiekt, a nie tablicę.
function will return the object, rather than an array
może popełnić błąd, ale myślę, że to zależy od użytkowników.
Zaczynając od odpowiedzi Agatona , jest to funkcja, która faktycznie zwraca poszukiwany element (lub null
jeśli nie został znaleziony), biorąc pod uwagę array
oraz callback
funkcję, która zwraca prawdziwą wartość dla „poprawnego” elementu:
function findElement(array, callback) {
var elem;
return array.some(function(e) {
if (callback(e)) {
elem = e;
return true;
}
}) ? elem : null;
});
Pamiętaj tylko, że to nie działa natywnie na IE8-, ponieważ nie obsługuje some
. Można podać polifill, alternatywnie zawsze jest klasyczna for
pętla:
function findElement(array, callback) {
for (var i = 0; i < array.length; i++)
if (callback(array[i])) return array[i];
return null;
});
Jest właściwie szybszy i bardziej kompaktowy. Ale jeśli nie chcesz wymyślać koła od nowa, sugeruję użycie biblioteki narzędziowej, takiej jak podkreślenie lub lodash.
Najkrótszy
var theAnswerObj = _.findWhere(array, {id : 42});