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)。 有关完整列表,请参阅浏览器兼容性