Відповіді:
Використовуйте find()
метод:
myArray.find(x => x.id === '45').foo;
Від MDN :
find()
Метод повертає перше значення в масиві, якщо елемент в масиві задовольняє умовам функції. В іншому випадкуundefined
повертається.
Якщо ви хочете знайти його індекс , скористайтеся findIndex()
:
myArray.findIndex(x => x.id === '45');
Від MDN :
findIndex()
Метод повертає індекс першого елемента в масиві , який задовольняє умову тестування функції. Інакше -1 повертається.
Якщо ви хочете отримати масив відповідних елементів, скористайтеся filter()
методом:
myArray.filter(x => x.id === '45');
Це поверне масив об’єктів. Якщо ви хочете отримати масив foo
властивостей, ви можете зробити це map()
методом:
myArray.filter(x => x.id === '45').map(x => x.foo);
Побічна примітка: такі методи, як find()
або filter()
, і функції стрілок не підтримуються старими браузерами (наприклад, IE), тому, якщо ви хочете підтримувати ці браузери, вам слід перекласти код за допомогою Babel (за допомогою поліфауни ).
Оскільки ви вже використовуєте jQuery, ви можете використовувати функцію grep, яка призначена для пошуку масиву:
var result = $.grep(myArray, function(e){ return e.id == id; });
Результат - масив із знайденими елементами. Якщо ви знаєте, що об’єкт завжди є і що він виникає лише один раз, ви можете просто скористатися, result[0].foo
щоб отримати значення. В іншому випадку слід перевірити довжину отриманого масиву. Приклад:
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
}
===
замість того ==
, щоб уникнути дивні проблеми з в JavaScript ==
оператора.
e.id
і id
будуть рядками, я вважаю, що це нормально використовувати ==
. Але якщо ви не впевнені, у вас можуть виникнути проблеми (оскільки '' == 0
є, true
але '' === 0
є false
). Не кажучи вже ===
про те, що швидше ( stackoverflow.com/questions/359494/… ).
===
оскільки він працює точно так само, як і ==
в інших мовах програмування. Я вважаю, що ==
в JavaScript не існує.
Іншим рішенням є створення об’єкта пошуку:
var lookup = {};
for (var i = 0, len = array.length; i < len; i++) {
lookup[array[i].id] = array[i];
}
... now you can use lookup[id]...
Це особливо цікаво, якщо вам потрібно зробити багато пошукових запитів.
Для цього не знадобиться значно більше пам’яті, оскільки ідентифікатори та об’єкти будуть спільними.
lookup
об’єкта - це марна трата часу.
ECMAScript 2015 пропонує метод find () для масивів:
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);
Він працює без зовнішніх бібліотек. Але якщо ви хочете підтримати старіший веб-переглядач, можливо, ви хочете включити цю полів .
myArray.find(d=>d.id===45).foo;
.
myArray.find(({ id }) => id === 45).foo
. Але це стара відповідь, написана до того, як синтаксис ES2015 був так само підтримуваний, як і зараз. @ Gothdo в відповідь в даний час є найбільш актуальною в потоці.
myArray.find(d => d.id === 45)?.foo
.
Underscore.js має для цього хороший метод:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'},etc.]
obj = _.find(myArray, function(obj) { return obj.id == '45' })
Я думаю, що найпростішим способом було б наступне, але він не працюватиме в Internet Explorer 8 (або раніше):
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
циклом.
for
цикл закінчується в першому збігу.
id
Спробуйте наступне
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]
Узагальнена та більш гнучка версія функції 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');
Це легко отримати за допомогою функції 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";
Приклад роботи: http://jsfiddle.net/hunter/Pxaua/
map
автоматично видаляє null
елементи. Мені це здається оманливим і для загальної концепції map
, оскільки результат не має однакової довжини оригінальної колекції.
Ви можете використовувати фільтри,
function getById(id, myArray) {
return myArray.filter(function(obj) {
if(obj.id == id) {
return obj
}
})[0]
}
get_my_obj = getById(73, myArray);
Хоча тут є багато правильних відповідей, багато з них не звертаються до факту, що це зайва дорога операція, якщо вона робиться більше одного разу. В крайньому випадку, це може стати причиною реальних проблем з роботою.
У реальному світі, якщо ви обробляєте багато предметів, продуктивність викликає занепокоєння, спочатку побудувати пошук:
var items = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}];
var lookup = items.reduce((o,i)=>o[i.id]=o,{});
Ви можете потрапити на товари у встановлений час так:
var bar = o[id];
Ви також можете використати Map замість об'єкта в якості пошуку: 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)
});
повертає об'єктний елемент, якщо його знайдено, в іншому випадку false
Якщо ви зробите це кілька разів, ви можете створити карту (ES6):
const map = new Map( myArray.map(el => [el.id, el]) );
Тоді ви можете просто зробити:
map.get(27).foo
Ось як я б про це пішов у чистому JavaScript, я, як мінімум, думаю про те, що працює в ECMAScript 3 або пізнішій версії. Він повертається, як тільки знайдеться відповідність.
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'
Більш родовий і короткий
function findFromArray(array,key,value) {
return array.filter(function (element) {
return element[key] == value;
}).shift();
}
у вашому випадку var element = findFromArray(myArray,'id',45)
це дасть вам весь елемент.
Ви можете спробувати Sugarjs з http://sugarjs.com/ .
Вона має дуже солодкий метод на масивах, .find
. Таким чином, ви можете знайти такий елемент:
array.find( {id: 75} );
Ви також можете передати об'єкт з більшістю властивостей до нього, щоб додати ще одне "де-пункт".
Зауважте, що Sugarjs розширює рідні об’єкти, і деякі люди вважають це дуже злим ...
find
цим і сталося . Моя пропозиція полягає в тому, що якщо ви хочете розширити власні прототипи, завжди використовуйте більш конкретні імена, залишаючи найпростіші для майбутніх стандартних розробок.
Спираючись на прийняту відповідь:
jQuery:
var foo = $.grep(myArray, function(e){ return e.id === foo_id})
myArray.pop(foo)
Або CoffeeScript:
foo = $.grep myArray, (e) -> e.id == foo_id
myArray.pop foo
Останнім часом мені доводиться стикатися з тим самим, у якому мені потрібно шукати рядок з величезного масиву.
Після деякого пошуку я знайшов, що легко впоратися з простим кодом:
Код:
var items = mydata.filter(function(item){
return item.word.toLowerCase().startsWith( 'gk );
})
Ітерація над будь-яким елементом масиву. Кожен предмет, який ви відвідуєте, перевірте його. Якщо це збіг, поверніть його.
Якщо ви просто хочете кодек:
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
}
І те саме, що використовує методи масиву 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];
}
Це можна зробити навіть у чистому JavaScript, використовуючи вбудовану функцію "фільтр" для масивів:
Array.prototype.filterObjects = function(key, value) {
return this.filter(function(x) { return x[key] === value; })
}
Тож тепер просто передайте "id" замість key
та "45" замість value
, і ви отримаєте повний об'єкт, що відповідає ідентифікатору 45. Так це було б,
myArr.filterObjects("id", "45");
Використовуйте 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
}
}
];
ФІЛЬТР
var getPerson = function(name){
return jsonObj.filter(function(obj) {
return obj.name === name;
});
}
.filter
метод використання obj.info
у вкладеному циклі. var getPerson = function(name){ return jsonObj.filter(function(obj) { return obj.info.filter(function(info) { return pets === false; }); }); }
Ми можемо використовувати методи 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 );
});
використовувати синтаксис ES6:
Array.find, Array.filter, Array.forEach, Array.map
Або скористайтеся Lodash https://lodash.com/docs/4.17.10#filter , Underscore https://underscorejs.org/#filter
Мені дуже сподобалася відповідь, яку надав Аарон Дігулла, але мені потрібно було зберегти масив об'єктів, щоб я міг переглядати її пізніше. Тому я змінив його на
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
Використання:
var retObj ={};
$.each(ArrayOfObjects, function (index, obj) {
if (obj.id === '5') { // id.toString() if it is int
retObj = obj;
return false;
}
});
return retObj;
Він повинен повернути об’єкт за ідентифікатором.
Це рішення також може бути корисним:
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");
Я зробив це так само, $.grep
і якщо один об'єкт виявиться, функція поверне об'єкт, а не масив.
function will return the object, rather than an array
може помилитися, але я думаю, це залежить від користувачів.
Починаючи з відповіді aggaton , це функція, яка фактично повертає шуканий елемент (або null
якщо його не знайдено), з огляду на функцію array
та callback
функцію, яка повертає правильне значення для "правильного" елемента:
function findElement(array, callback) {
var elem;
return array.some(function(e) {
if (callback(e)) {
elem = e;
return true;
}
}) ? elem : null;
});
Пам'ятайте лише, що це не працює в IE8-, оскільки воно не підтримує some
. Можна заповнити полів, або завжди є класичний for
цикл:
function findElement(array, callback) {
for (var i = 0; i < array.length; i++)
if (callback(array[i])) return array[i];
return null;
});
Це насправді швидше і компактніше. Але якщо ви не хочете винаходити колесо, я пропоную використовувати бібліотеку утиліт, наприклад, підкреслення або позначення.
Найкоротший,
var theAnswerObj = _.findWhere(array, {id : 42});