Ответ 1
var result = jsObjects.filter(function( obj ) {
return obj.b == 6;
});
Скажем, у меня есть массив из четырех объектов:
var jsObjects = [
{a: 1, b: 2},
{a: 3, b: 4},
{a: 5, b: 6},
{a: 7, b: 8}
];
Есть ли способ, которым я могу получить третий объект ({a: 5, b: 6}
) по значению свойства b
, например, без цикла for...in
?
var result = jsObjects.filter(function( obj ) {
return obj.b == 6;
});
Я не знаю, почему вы против цикла for (предположительно вы имели в виду цикл for, а не специально для..), они быстро и легко читаются. Во всяком случае, здесь есть несколько вариантов.
Для цикла:
function getByValue(arr, value) {
for (var i=0, iLen=arr.length; i<iLen; i++) {
if (arr[i].b == value) return arr[i];
}
}
.filter
function getByValue2(arr, value) {
var result = arr.filter(function(o){return o.b == value;} );
return result? result[0] : null; // or undefined
}
.forEach
function getByValue3(arr, value) {
var result = [];
arr.forEach(function(o){if (o.b == value) result.push(o);} );
return result? result[0] : null; // or undefined
}
Если, с другой стороны, вы действительно имели значение для.. и хотите найти объект с любым свойством со значением 6, то вы должны использовать его для..., если вы не передадите имена для проверки. например.
function getByValue4(arr, value) {
var o;
for (var i=0, iLen=arr.length; i<iLen; i++) {
o = arr[i];
for (var p in o) {
if (o.hasOwnProperty(p) && o[p] == value) {
return o;
}
}
}
}
jsObjects.find(x => x.b === 6)
Из MDN:
Метод
find()
возвращает значение в массиве, если элемент в массиве удовлетворяет предоставленной функции тестирования. В противном случае возвращаетсяundefined
.
Примечание: методы, подобные find()
, и функции стрелок не поддерживаются всеми браузерами, но это не значит, что вы не можете использовать эти функции прямо сейчас. Просто используйте Babel - он преобразует код ES6 в ES5.
Использование underscore.js:
var foundObject = _.findWhere(jsObjects, {b: 6});
Если я правильно понял, вы хотите найти объект в массиве, чье свойство b
6
?
var found;
jsObjects.some(function (obj) {
if (obj.b === 6) {
found = obj;
return true;
}
});
Или, если вы используете подчеркивание:
var found = _.select(jsObjects, function (obj) {
return obj.b === 6;
});
Похоже, что в предложении ECMAScript 6 есть методы Array
find()
и findIndex()
. MDN также предлагает полиполки, которые вы можете включить, чтобы получить их функциональность во всех браузерах.
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) return false;
}
return (element > 1);
}
console.log( [4, 6, 8, 12].find(isPrime) ); // undefined, not found
console.log( [4, 5, 8, 12].find(isPrime) ); // 5
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) return false;
}
return (element > 1);
}
console.log( [4, 6, 8, 12].findIndex(isPrime) ); // -1, not found
console.log( [4, 6, 7, 12].findIndex(isPrime) ); // 2
Попробуйте Фильтр массива для фильтрации array of objects
с помощью property
.
var jsObjects = [
{a: 1, b: 2},
{a: 3, b: 4},
{a: 5, b: 6},
{a: 7, b: 8}
];
с использованием метода фильтра массивов:
var filterObj = jsObjects.filter(function(e) {
return e.b == 6;
});
для цикла in:
for (var i in jsObjects) {
if (jsObjects[i].b == 6) {
console.log(jsObjects[i]); // {a: 5, b: 6}
}
}
Рабочая скрипта: https://jsfiddle.net/uq9n9g77/
Как насчет использования _.find(collection, [predicate=_.identity], [fromIndex=0])
lo-dash, чтобы получить объект из массива объектов по значению свойства объекта. Вы можете сделать что-то вроде этого:
var o = _.find(jsObjects, {'b': 6});
Аргументы:
collection (Array|Object): The collection to inspect.
[predicate=_.identity] (Function): The function invoked per iteration.
[fromIndex=0] (number): The index to search from.
Возвращает
(*): Returns the matched element (in your case, {a: 5, b: 6}), else undefined.
С точки зрения производительности, _.find()
работает быстрее, так как он только вытаскивает первый объект с свойством {'b': 6}
, если предположить, что ваш массив содержит несколько объектов с соответствующим набором свойств (ключ: значение), тогда вы должны использовать метод _.filter()
. Поэтому в вашем случае, поскольку ваш массив имеет один объект с этим свойством, я бы использовал _.find()
.
Если вы ищете единственный результат, а не массив, могу ли я предложить уменьшить?
Вот решение в plain 'ole javascript, которое возвращает соответствующий объект, если он существует, или null, если нет.
var result = arr.reduce(function(prev, curr) { return (curr.b === 6) ? curr : prev; }, null);
Вы можете использовать метод Array.filter: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter
Смотрите эту документацию https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values
Пример:
var inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function findCherries(fruit) {
return fruit.name === 'cherries';
}
console.log(inventory.find(findCherries));
// { name: 'cherries', quantity: 5 }
Чтобы получить первый объект из массива объектов по определенному значению свойства:
function getObjectFromObjectsArrayByPropertyValue(objectsArray, propertyName, propertyValue) {
return objectsArray.find(function (objectsArrayElement) {
return objectsArrayElement[propertyName] == propertyValue;
});
}
function findObject () {
var arrayOfObjectsString = document.getElementById("arrayOfObjects").value,
arrayOfObjects,
propertyName = document.getElementById("propertyName").value,
propertyValue = document.getElementById("propertyValue").value,
preview = document.getElementById("preview"),
searchingObject;
arrayOfObjects = JSON.parse(arrayOfObjectsString);
console.debug(arrayOfObjects);
if(arrayOfObjects && propertyName && propertyValue) {
searchingObject = getObjectFromObjectsArrayByPropertyValue(arrayOfObjects, propertyName, propertyValue);
if(searchingObject) {
preview.innerHTML = JSON.stringify(searchingObject, false, 2);
} else {
preview.innerHTML = "there is no object with property " + propertyName + " = " + propertyValue + " in your array of objects";
}
}
}
pre {
padding: 5px;
border-radius: 4px;
background: #f3f2f2;
}
textarea, button {
width: 100%
}
<fieldset>
<legend>Input Data:</legend>
<label>Put here your array of objects</label>
<textarea rows="7" id="arrayOfObjects">
[
{"a": 1, "b": 2},
{"a": 3, "b": 4},
{"a": 5, "b": 6},
{"a": 7, "b": 8, "c": 157}
]
</textarea>
<hr>
<label>property name: </label> <input type="text" id="propertyName" value="b"/>
<label>property value: </label> <input type="text" id="propertyValue" value=6 />
</fieldset>
<hr>
<button onclick="findObject()">find object in array!</button>
<hr>
<fieldset>
<legend>Searching Result:</legend>
<pre id="preview">click find</pre>
</fieldset>
Использование find с привязкой для передачи определенных значений ключа функции обратного вызова.
function byValue(o) {
return o.a === this.a && o.b === this.b;
};
var result = jsObjects.find(byValue.bind({ a: 5, b: 6 }));
var jsObjects = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8}];
для доступа к третьему объекту используйте: jsObjects[2];
для доступа к третьему объекту b используйте: jsObjects[2].b;