Jquery 如何在 Array 中通过属性查找 Object

假设我有一组“目的”对象:

//array of purpose objects:
var purposeObjects = [
{purpose: "daily"},
{purpose: "weekly"},
{purpose: "monthly"}
];

(为简单起见,我省略了其他属性)

现在我想要一个方法,如果找到匹配的目的名称,它将返回一个特定的对象。

这没有用:

function findPurpose(purposeName){
return $.grep(purposeObjects, function(){
return this.purpose == purposeName;
});
};


findPurpose("daily");

但它实际上返回一个空数组:

[]

我使用的是 JQuery 1.5.2。我也试过使用 $. each () ,但没有成功。 显然,大多数 JQuery 方法都是为使用 DOM 元素(例如 filter())而设计的。

对于如何实现这一点有什么想法吗?

129422 次浏览

错误在于不能在 grep 中使用 this,但必须使用对元素的引用。这种方法是有效的:

function findPurpose(purposeName){
return $.grep(purposeObjects, function(n, i){
return n.purpose == purposeName;
});
};


findPurpose("daily");

报税表:

[Object { purpose="daily"}]

您应该在 grep 函数中传递对项的引用:

function findPurpose(purposeName){
return $.grep(purposeObjects, function(item){
return item.purpose == purposeName;
});
};

例子

不需要 jQuery。

JavaScript 数组有一个 找到方法,所以只需要一行代码就可以实现:

array.find((o) => { return o[propertyName] === propertyValue })

例子


const purposeObjects = [
{purpose: "daily"},
{purpose: "weekly"},
{purpose: "monthly"}
];


purposeObjects.find((o) => { return o["purpose"] === "weekly" })


// output -> {purpose: "weekly"}

如果你需要 IE 兼容性,在你的代码中导入这个 填料

我个人使用了一个更通用的函数,它适用于任何数组的任何属性:

function lookup(array, prop, value) {
for (var i = 0, len = array.length; i < len; i++)
if (array[i] && array[i][prop] === value) return array[i];
}

你可以这么说:

lookup(purposeObjects, "purpose", "daily");

使用 Underscore.js findWhere 函数(http://underscorejs.org/#findWhere) :

var purposeObjects = [
{purpose: "daily"},
{purpose: "weekly"},
{purpose: "monthly"}
];


var daily = _.findWhere(purposeObjects, {purpose: 'daily'});

daily等于:

{"purpose":"daily"}

这是小提琴: http://jsfiddle.net/spencerw/oqbgc21x/

要返回多个值(如果在数组中有更多值) ,可以使用 _.where(...)

最好,最快的方法是

function arrayLookup(array, prop, val) {
for (var i = 0, len = array.length; i < len; i++) {
if (array[i].hasOwnProperty(prop) && array[i][prop] === val) {
return array[i];
}
}
return null;
}

还有一个办法:

function firstOrNull(array, expr) {
for (var i = 0; i < array.length; i++) {
if (expr(array[i]))
return array[i];
}
return null;
}

使用方法: firstOrNull([{ a: 1, b: 2 }, { a: 3, b: 3 }], function(item) { return item.a === 3; });

这个函数不会为数组中的每个元素执行(对于大型数组来说,它很有价值)

如果您的数组实际上是一组 JQuery 对象,那么简单地使用 。过滤()方法如何呢?

purposeObjects.filter('[purpose="daily"]')

我为我的角度应用程序创建了一个 util 服务,它有两个经常使用的功能。

例如,您有对象。

首先递归地从对象获取值,而不抛出未定义的错误。

{道具: { nestedProp1: { nestedProp2: somevalue }}} ; 在没有未定义检查的情况下获得 nestedProp22。

基础上的第二个滤波器阵列

[{道具: { nestedProp1: { nestedProp2: somevalue1}}} ,{道具: { nestedProp1: { nestedProp2: somevalue2}}}] ;

使用 nestedProp2 = somevalue2从数组中查找对象

app.service('UtilService', function(httpService) {
this.mapStringKeyVal = function(map, field) {
var lastIdentifiedVal = null;
var parentVal = map;
field.split('.').forEach(function(val){
if(parentVal[val]){
lastIdentifiedVal = parentVal[val];
parentVal = parentVal[val];
}
});
return lastIdentifiedVal;
}




this.arrayPropFilter = function(array, field,value) {
var lastIdentifiedVal = null;
var mapStringKeyVal = this.mapStringKeyVal;
array.forEach(function(arrayItem){
var valueFound = mapStringKeyVal(arrayItem,field);
if(!lastIdentifiedVal  && valueFound && valueFound==value){
lastIdentifiedVal = arrayItem;
}
});
return lastIdentifiedVal;
}});

为了解决当前问题,请注入 UtilService 并调用,

UtilService.arrayPropFilter(purposeArray,'purpose','daily');

或者更高级

UtilService.arrayPropFilter(purposeArray,'purpose.nestedProp1.nestedProp2','daily');

Javascript 有一个函数: 数组,原型,查找

function isBigEnough(element) {
return element >= 15;
}


[12, 5, 8, 130, 44].find(isBigEnough); // 130

将回调扩展到函数并不困难。但是这与 IE 不兼容(部分与 Edge 也不兼容)。要获得完整的列表,请查看 浏览器兼容性

从 polyfill Array.Prototype.find 的 Array.find 代码中复制,并添加数组作为第一个参数。

可以将搜索词作为谓词函数传递

// Example
var listOfObjects = [{key: "1", value: "one"}, {key: "2", value: "two"}]
var result = findInArray(listOfObjects, function(element) {
return element.key == "1";
});
console.log(result);


// the function you want
function findInArray(listOfObjects, predicate) {
if (listOfObjects == null) {
throw new TypeError('listOfObjects is null or not defined');
}


var o = Object(listOfObjects);


var len = o.length >>> 0;


if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}


var thisArg = arguments[1];


var k = 0;


while (k < len) {
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return kValue;
}
k++;
}


return undefined;
}