jquery如何在数组中find一个Object by属性

鉴于我有一个“目的”对象的数组:

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

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

现在我想有一个方法返回一个特定的对象,如果find匹配的用途名称。

这不工作:

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

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

 [] 

我正在使用JQuery 1.5.2。 我也尝试了$ .each(),但没有运气。 很显然,大多数JQuery方法都是为DOM元素(比如filter()

任何想法如何实现这一目标?

最快的方式(即使没有jQuery,它也能工作):

 var findPurpose = function(purposeName) { for (var i = 0, len = purposeObjects.length; i < len; i++) { if (purposeObjects[i].purpose === purposeName) return purposeObjects[i]; // Return as soon as the object is found } return null; // The object was not found } 

注意

jQuery $ .grep(或其他过滤函数)不是最佳解决scheme。

$.grep函数将遍历数组的所有元素,即使在循环中已经findsearch的对象。 从jQuery的grep文档:

$ .grep()方法根据需要从数组中删除项目,以便所有剩余的项目都通过提供的testing。 testing是一个函数,它传递一个数组项和数组中的项的索引。 只有当testing返回true时,项目才会在结果数组中。

你应该通过grep函数中的项目参考:

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

错误是你不能在grep中使用this ,但是你必须使用对元素的引用。 这工作:

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

收益:

 [Object { purpose="daily"}] 

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

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

另一个解决scheme:

 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对象,那么简单地使用.filter()方法呢?

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

我为我的angular度应用程序创build了一个util服务。 它有两个常用的function。

比如你有对象。

首先从对象recursion获取值,而不会引发未定义的错误。

{prop:{nestedProp1:{nestedProp2:somevalue}}}; 得到nestedProp2 2没有未定义的检查。

第二个filter数组

[{prop:{nestedProp1:{nestedProp2:somevalue1}}},{prop:{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; }}); 

为当前问题的解决scheme。 注入UtilService并调用,

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

或者更先进

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

JavaScript有一个function就是: Array.prototype.find 。 作为例子

 function isBigEnough(element) { return element >= 15; } [12, 5, 8, 130, 44].find(isBigEnough); // 130 

将callback扩展到一个函数并不困难。 然而,这与IE不兼容(部分与Edge)。 有关完整列表,请参阅浏览器兼容性