这个问题在这里已经有了答案:Find object by id in an array of JavaScript objects (36 answers) 4 年前关闭。
假设我有一个包含四个对象的数组:
var jsObjects = [
{a: 1, b: 2},
{a: 3, b: 4},
{a: 5, b: 6},
{a: 7, b: 8}
];
有没有一种方法可以通过属性 b
的值获取第三个对象 ({a: 5, b: 6}
),例如没有 for...in
循环?
b = 6
的对象
Filter
对象数组,其属性与值匹配,返回数组:
var result = jsObjects.filter(obj => {
return obj.b === 6
})
请参阅MDN Docs on Array.prototype.filter()
const jsObjects = [ {a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8} ] 让结果 = jsObjects.filter (obj => { return obj.b === 6 }) console.log(result)
Find
数组中第一个元素/对象的值,否则返回 undefined
。
var result = jsObjects.find(obj => {
return obj.b === 6
})
请参阅MDN Docs on Array.prototype.find()
const jsObjects = [ {a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8} ] 让结果 = jsObjects.find (obj => { return obj.b === 6 }) console.log(result)
jsObjects.find(x => x.b === 6)
来自 MDN:
如果数组中的元素满足提供的测试函数,则 find() 方法返回数组中的值。否则返回未定义。
旁注:旧版浏览器(如 IE)不支持 find()
和箭头函数等方法,因此如果您想支持这些浏览器,则应使用 Babel 转译您的代码。
find()
和箭头函数之类的方法”。
filter()
返回对象的副本,不是原始对象,因此更改不会反映在原始数组中
filter()
的答案:它只返回第一个匹配项。
我不知道您为什么反对 for 循环(大概您的意思是 for loop
,而不是专门的 for..in
),它们快速且易于阅读。无论如何,这里有一些选择。
对于循环:
function getByValue(arr, value) {
for (var i=0, iLen=arr.length; i<iLen; i++) {
if (arr[i].b == value) return arr[i];
}
}
。筛选
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
}
另一方面,如果您确实是指 for..in 并且想要查找具有任何值为 6 的属性的对象,那么您必须使用 for..in 除非您将名称传递给检查。
例子
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;
}
}
}
}
arr.length
存储在 iLen
中而不是在 for 条件中直接使用 arr.length
作为 i<arr.length
的任何具体原因?
达到要求的方法:
使用 Array.find() 方法:
const jsObject = [ {a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8} ];常量过滤结果 = jsObject.find((e) => eb == 6); console.log(filteredResult);
使用 Array.filter() 方法:
const jsObjects = [ {a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8} ]; const filterObj = jsObjects.filter((e) => eb == 6); console.log(filterObj[0]);
使用 for...in 循环:
const jsObjects = [ {a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8} ]; for (const i in jsObjects) { if (jsObjects[i].b == 6) { console.log(jsObjects[i]); } }
好的,有几种方法可以做到这一点,但让我们从最简单和最新的方法开始,这个函数称为 find()
。
当你使用 find
时要小心,因为即使 IE11 也不支持它,所以它需要被转译......
所以你有这个对象,正如你所说:
var jsObjects = [
{a: 1, b: 2},
{a: 3, b: 4},
{a: 5, b: 6},
{a: 7, b: 8}
];
你可以编写一个函数并像这样得到它:
function filterValue(obj, key, value) {
return obj.find(function(v){ return v[key] === value});
}
并使用这样的功能:
filterValue(jsObjects, "b", 6); //{a: 5, b: 6}
同样在 ES6 中用于更短的版本:
const filterValue = (obj, key, value)=> obj.find(v => v[key] === value);
此方法只返回第一个匹配的值...,为了更好的结果和浏览器支持,您可以使用 filter
:
const filterValue = (obj, key, value)=> obj.filter(v => v[key] === value);
我们将返回 [{a: 5, b: 6}]
...
此方法将返回一个数组而不是...
您也可以简单地使用 for 循环,创建一个这样的函数:
function filteredArray(arr, key, value) {
const newArray = [];
for(i=0, l=arr.length; i<l; i++) {
if(arr[i][key] === value) {
newArray.push(arr[i]);
}
}
return newArray;
}
并这样称呼它:
filteredArray(jsObjects, "b", 6); //[{a: 5, b: 6}]
请参阅此文档Array.prototype.find()
例子:
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 }
undefined?
使用 underscore.js:
var foundObject = _.findWhere(jsObjects, {b: 6});
_.find
:stackoverflow.com/a/40958199/12695188
看起来在 ECMAScript 6 提案中有 Array
方法 find()
和 findIndex()
。 MDN 还提供了 polyfill,您可以将其包含在内以在所有浏览器中获取这些功能。
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
如果我理解正确,您想在数组中找到 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;
});
some
只返回 true 或 false,它不返回匹配的对象。
.some()
用于确定数组中的某个元素是否通过测试。在这种情况下,最好使用 .forEach()
,因为您已经决定将结果分配给一个变量。
.some
中的 return true
本质上类似于 for 循环中的 break
。
如果您正在寻找单个结果而不是数组,我可以建议减少吗?
这是一个简单的 'ole javascript 解决方案,如果存在则返回匹配的对象,如果不存在则返回 null。
var result = arr.reduce(function(prev, curr) { return (curr.b === 6) ? curr : prev; }, null);
您可以将它与箭头功能一起使用,如下所示:
var demoArray = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
var result = demoArray.filter( obj => obj.name === 'apples')[0];
console.log(result);
// {name: 'apples', quantity: 2}
如何使用 lo-dash 的 _.find(collection, [predicate=_.identity], [fromIndex=0])
通过对象属性值从对象数组中获取对象。你可以这样做:
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}
的第一个对象,另一方面,如果假设您的数组包含多个具有匹配属性集 (key:value) 的对象,那么您应该考虑使用 _.filter()
方法。因此,在您的情况下,由于您的数组有一个具有此属性的对象,因此我将使用 _.find()
。
使 this answer 中最好/最快的部分更易于重复使用和清除:
function getElByPropVal(myArray, prop, val){
for (var i = 0, length = myArray.length; i < length; i++) {
if (myArray[i][prop] == val){
return myArray[i];
}
}
}
var result = jsObjects.filter(x=> x.b === 6);
会更好,在过滤器中使用 return 有时你不能得到结果(我不知道为什么)
通过特定属性值从对象数组中获取第一个对象:
函数 getObjectFromObjectsArrayByPropertyValue(objectsArray, propertyName, propertyValue) { return objectsArray.find(function (objectsArrayElement) { return objectsArrayElement[propertyName] == propertyValue; }); } 函数 findObject () { var arrayOfObjectsString = document.getElementById("arrayOfObjects").value, arrayOfObjects, propertyName = document.getElementById("propertyName").value, propertyValue = document.getElementById("propertyValue").value, preview = document.getElementById("preview"), 搜索对象; arrayOfObjects = JSON.parse(arrayOfObjectsString); console.debug(arrayOfObjects); if(arrayOfObjects && propertyName && propertyValue) { searchObject = getObjectFromObjectsArrayByPropertyValue(arrayOfObjects, propertyName, propertyValue); if(searchingObject) { preview.innerHTML = JSON.stringify(searchingObject, false, 2); } else { preview.innerHTML = "您的对象数组中没有具有属性的对象 " + propertyName + " = " + propertyValue + ""; } } } pre { 填充:5px;边框半径:4px;背景:#f3f2f2; } textarea, button { width: 100% }
使用 find 和 bind 将特定的键值传递给回调函数。
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;
不定期副业成功案例分享
result[0]
将是第一个(唯一)对象。