2013-11-10 34 views
3

在给定的searchObject规格中是否有任何简短而整洁的方式查找以下列表中的项目?javascript中的多个字段比较

var list = [ 
    { id:1, name: "foo", description: "description 1" }, 
    { id:2, name: "bar", description: "description 2" }, 
    { id:3, name: "baz", description: "description 3" }, 
]; 

var searchObject = { id: 2, name: "bar" }; 

searchObject确实一定在列表中的项目的所有属性。我需要属性之间的运算符为(id == 2 & & name ==“bar”)。以下是我所想到的。有什么本地的JavaScript可以做到这一点?

for (var i in list) { 
    var found = true; 
    for (var p in searchObject) { 
     if (list[i][p] !== searchObject[p]) { 
      found = false; 
      break; 
     } 
    } 
    if(found) return list[i]; 
} 
+0

请不要在数组中使用'for(x in y)'。 [它不会做你的想法](http://stackoverflow.com/a/500531/36866) – some

回答

0

根据我的经验,如果解决方案存在,它不会比你的更好。

最好不要在数组中使用for...in语句,因为它枚举了数组的属性,而不是元素。考虑以下几点:

Array.prototype.test = function() { }; 
for (var i in q) console.log(i); 

此代码将输出test这可能不是你可能期望。

无论如何,对于这种事情我使用lo-dash。它的_.find(...)方法完全符合你的需求,你可以看看这个方法的源代码,我认为这是最有效的实现。

3

不,没有原生的方式。有些人可能更喜欢以下内容,因为它的更多javascripty,但它当然不具备原始版本所具有的卓越浏览器支持。

var matches = list.filter(function(arrElem){ 
    return Object.keys(searchObject).every(function(prop){ 
     return searchObject[prop] === arrElem[prop]; 
    }); 
}); 

请注意,这将返回一个包含所有匹配项的数组,而不仅仅是像您的第一个匹配项。还请注意,与您的不同,这不会测试searchObject上的继承的可枚举属性,尽管您可能不想搜索继承的属性。

ps,许多这些“我希望js有一个更好的方式做x”的愿望由underscore.js满足。特别是,findWhere方法是你所追求的:

var match = _.findWhere(list, searchObject); 
+0

“javascripty”,你的意思是功能? –

+0

@ChristopherHarris有点儿......也许更像是强调javascripts必需的面向对象/功能性思想的独特混合。 – goat