У меня есть массив:
myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}, etc.]
Я не могу изменить структуру массива. Мне передается id 45
, и я хочу получить 'bar'
для этого объекта в массиве.
Как это сделать в JavaScript или с помощью jQuery?
Используйте метод 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) {
// not found
} else if (result.length == 1) {
// access the foo property using result[0].foo
} else {
// multiple items found
}
===
вместо ==
, чтобы избежать странных проблем с оператором 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]...
Это особенно интересно, если вам нужно много искать.
Это не потребует гораздо больше памяти, так как идентификаторы и объекты будут совместно использоваться.
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);
Работает без внешних библиотек. Но если вы хотите более старую поддержку браузера, вы можете включить this polyfill.
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
.
Попробуйте выполнить
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
jQuery автоматически удаляет 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];
Вы также можете использовать карту вместо объекта в качестве поиска: 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
Вот как я буду заниматься этим в чистом 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'
Если вы делаете это несколько раз, вы можете настроить карту (ES6):
const map = new Map( myArray.map(el => [el.id, el]) );
Тогда вы можете просто сделать:
map.get(27).foo
Основываясь на принятом ответе:
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
Вы можете попробовать Sugarjs из http://sugarjs.com/.
Он имеет очень сладкий метод в массивах, .find
. Итак, вы можете найти такой элемент:
array.find( {id: 75} );
Вы также можете передать объект с большим количеством свойств, чтобы добавить другое "where-clause".
Обратите внимание, что Sugarjs расширяет родные объекты, а некоторые люди считают это очень злым...
find
. Мое предложение состоит в том, что если вы хотите расширить собственные прототипы, всегда используйте более конкретные имена, оставляя самые простые из них для будущих стандартных разработок.
Вы можете сделать это даже в чистом JavaScript, используя встроенную функцию "filter" для массивов:
Array.prototype.filterObjects = function(key, value) {
return this.filter(function(x) { return x[key] === value; })
}
Итак, вместо "t22 > вместо" t22 "вместо" t21 "и" 45 "вы просто передадите" id ", и вы получите полный объект, соответствующий идентификатору 45. Таким образом, это будет
myArr.filterObjects("id", "45");
Итерации по любому элементу массива. Для каждого элемента, который вы посещаете, проверьте этот элемент. Если это совпадение, верните его.
Если вам просто нужен код:
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 Array:
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];
}
Используйте функцию 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; }); }); }
Мне очень понравился ответ, предоставленный Аароном Дигуллой, но мне нужно было сохранить свой массив объектов, чтобы потом продолжить его. Поэтому я изменил его на
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
Пока браузер поддерживает ECMA-262, 5-е издание (декабрь 2009 г.), это должно работать почти с одним слоем:
var bFound = myArray.some(function (obj) {
return obj.id === 45;
});
bFound
- это просто логическое значение, которое true
если элемент удовлетворяет требуемому условию.
Это решение может также помочь:
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
может получить ошибку, но я думаю, что это зависит от пользователей.
Использование:
var retObj ={};
$.each(ArrayOfObjects, function (index, obj) {
if (obj.id === '5') { // id.toString() if it is int
retObj = obj;
return false;
}
});
return retObj;
Он должен возвращать объект по id.
Более общий и короткий
function findFromArray(array,key,value) {
return array.filter(function (element) {
return element[key] == value;
}).shift();
}
в вашем случае Ex. var element = findFromArray(myArray,'id',45)
, который даст вам весь элемент.
Мы можем использовать методы Jquery $.each()/$. Grep() var data= []; $.each(array,function(i){if(n !== 5 && я > 4){data.push(item)}}
var data= []; $.each(array,function(i){if(n !== 5 && я > 4){data.push(item)}}
или же
var data = $.grep(array, function( n, я ) { return ( n !== 5 && я > 4 ); });
использовать синтаксис ES6: Array.find, Array.filter, Array.forEach, Array.map
Или используйте Lodash https://lodash.com/docs/4.17.10#filter, Подчеркните https://underscorejs.org/#filter
Рассмотрим "axesOptions" как массив объектов с форматом объекта, являющимся {: field_type = > 2,: fields = > [1,3,4]}
function getFieldOptions(axesOptions,choice){
var fields=[]
axesOptions.each(function(item){
if(item.field_type == choice)
fields= hashToArray(item.fields)
});
return fields;
}
Кратчайший,
var theAnswerObj = _.findWhere(array, {id : 42});
Начиная с aggaton answer, это функция, которая фактически возвращает желаемый элемент (или null
, если не найден), учитывая array
и a callback
, которая возвращает правдивое значение для "правильного" элемента:
function findElement(array, callback) {
var elem;
return array.some(function(e) {
if (callback(e)) {
elem = e;
return true;
}
}) ? elem : null;
});
Просто помните, что это не работает на IE8, поскольку оно не поддерживает some
. A polyfill может быть предусмотрен, альтернативно всегда существует классический цикл for
:
function findElement(array, callback) {
for (var i = 0; i < array.length; i++)
if (callback(array[i])) return array[i];
return null;
});
Это на самом деле быстрее и компактнее. Но если вы не хотите изобретать колесо, я предлагаю использовать библиотеку служебных программ, например, подчеркивание или lodash.
Мой способ найти индекс массива:
index = myArray.map(getItemId).indexOf(id);
getItemId: function(item) {
return item.id;
}
// to get foo property use index
myArray[index].foo
//If you want to use ES6
index = myArray.map((i) => i.id).indexOf(id)
myArray[index].foo
Использовать метод фильтрации jQuery:
$(myArray).filter(function()
{
return this.id == desiredId;
}).first();
Это вернет первый элемент с указанным идентификатором.
Он также имеет приятный формат С# LINQ.
filter
предназначен для элементов, а не массивов. Вместо этого используйте метод grep
.