通过属性值从对象数组中获取JavaScript对象

假设我有一个包含四个对象的数组:

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循环?

1672441 次浏览

Filter对象数组,其属性匹配值,返回数组:

var result = jsObjects.filter(obj => {return obj.b === 6})

MDN Docs onArray.prototype.filter()

const jsObjects = [{a: 1, b: 2},{a: 3, b: 4},{a: 5, b: 6},{a: 7, b: 8}]
let result = jsObjects.filter(obj => {return obj.b === 6})
console.log(result)

Find数组中第一个元素/对象的值,否则返回undefined

var result = jsObjects.find(obj => {return obj.b === 6})

MDN Docs onArray.prototype.find()

const jsObjects = [{a: 1, b: 2},{a: 3, b: 4},{a: 5, b: 6},{a: 7, b: 8}]
let result = jsObjects.find(obj => {return obj.b === 6})
console.log(result)

如果我理解正确,您想在数组中找到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;});

我不知道你为什么反对for循环(大概你的意思是for loop,而不是for..in),它们快速且易于阅读。总之,这里有一些选项。

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
}

.对于每个

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;}}}}

看起来在ECMAScript 6提案中有Array方法find()findIndex()。MDN还提供了多边形,您可以包含这些方法以在所有浏览器中获得这些功能。

#0

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 foundconsole.log( [4, 5, 8, 12].find(isPrime) ); // 5

#0

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 foundconsole.log( [4, 6, 7, 12].findIndex(isPrime) ); // 2
var jsObjects = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8}];

要访问第三个对象,请使用:jsObjects[2];
要访问第三个对象b值,请使用:jsObjects[2].b;

使用underscore.js:

var foundObject = _.findWhere(jsObjects, {b: 6});

如果你正在寻找一个单一的结果,而不是一个数组,我可以建议减少吗?

这是一个简单的'ole javascript解决方案,如果存在匹配对象,则返回一个匹配对象,如果不存在则返回null。

var result = arr.reduce(function(prev, curr) { return (curr.b === 6) ? curr : prev; }, null);
jsObjects.find(x => x.b === 6)

来自MDN:

如果数组中的元素满足提供的测试函数,#0方法返回数组中的一个值。否则返回undefined


附注:旧浏览器(如IE)不支持find()和箭头函数等方法,因此如果您想支持这些浏览器,您应该使用巴别塔转换代码。

要通过特定属性值从对象数组中获取第一个对象:

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>

达到需求的方法:

  1. 使用Array.find()方法:

const jsObject = [{a: 1, b: 2},{a: 3, b: 4},{a: 5, b: 6},{a: 7, b: 8}];
const filteredResult = jsObject.find((e) => e.b == 6);
console.log(filteredResult);

  1. 使用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) => e.b == 6);
console.log(filterObj[0]);

  1. 使用为…在循环:

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(collection, [predicate=_.identity], [fromIndex=0]) of低破折号通过对象属性值从对象数组中获取对象。你可以这样做:

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()

使用查找与绑定将特定键值传递给回调函数。

   function byValue(o) {return o.a === this.a && o.b === this.b;};
var result = jsObjects.find(byValue.bind({ a: 5, b: 6 }));

留档#0

示例:

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 }

您也可以将它与箭头函数一起使用,如下所示:

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}
var result = jsObjects.filter(x=> x.b === 6);

会更好,在过滤器中使用返回有时你无法得到结果(我不知道为什么)

使这个答案中最好/最快的部分更加可重用和清晰:

function getElByPropVal(myArray, prop, val){for (var i = 0, length = myArray.length; i < length; i++) {if (myArray[i][prop] == val){return myArray[i];}}}

OK,有几种方法可以做到这一点,但让我们从最简单和最新的方法开始,这个函数称为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}]