我想根据该对象的唯一属性(即一个键)从对象数组中提取特定对象。
在下文中,我正在搜索' arr'密钥是8。
var myElement = arr.filter(function(element) {
return element.key === 8;
});
这样可行,但每次运行时,即使找到了正确的元素,它也会迭代遍历数组中的所有元素。例如,如果它在索引4处找到myElement,但是数组中有100个元素,则该代码段的运行速度比其需要的数量多25倍。
是否有更有效的方法,或找到myElement时终止filter()的方法?
我觉得我错过了一些明显的东西......
答案 0 :(得分:2)
您实际上需要一个find
函数,该函数在找到第一个匹配项时返回。如果您使用的是ECMAScript 6规范,则可以使用Array.prototype.find
,或者您可以实现一个简单的find
:
function find8(arr) {
// type checks skipped for brevity
var i = 0,
j = arr.length;
for (; i < j; i++) {
if (arr[i].key === 8) {
return arr[i];
}
}
throw new Error('Not found');
}
如果你想要一个更通用的解决方案来接受谓词(即functions
返回一个布尔值),你可以编写一个更通用的函数,如:
function find(arr, predicate) {
// Again, type checks skipped for brevity
var i = 0,
j = arr.length;
for (; i < j; i++) {
// Note the condition is now a call to the predicate function
if (predicate(arr[i])) {
return arr[i];
}
}
throw new Error('Not found');
}
答案 1 :(得分:1)
for (var i=0; i<arr.length; i++) {
if (arr[i].key === 8) {
console.log('FOUND ITEM AT KEY '+8);
break;
}
}
答案 2 :(得分:1)
听起来你最好用这样的东西:
function findByKey(items, key) {
for (var index = 0; index < items.length; index++) {
var item = items[index];
if (item.key === key) {
return item;
}
}
return null;
}
请注意,如果您的列表已排序,您可以通过执行二进制搜索来改进它。虽然我个人建议散列(假设相同的密钥不会被使用两次)。类似的东西:
var array = [/* your data here... */];
var map = {};
//do this once; or once each time your array changes
for (var index = 0; index < array.length; index++) {
var item = array[index];
map[item.key] = item;
}
//now find things by doing this
var itemWithKey8 = map[8];
答案 3 :(得分:1)
我通过一个简单的for
循环来处理这个问题(使用了一个通用的重用函数):
function findObject(arr, cond)
for (i = 0; i < arr.length; i++) {
if (cond(arr[i]){
return arr[i];
}
}
}
// now call fincObject(myArray, function(element){element.key === 8})
或者,如果您知道要多次这样做,请创建一个应该很多的映射:
function makeMapping(arr, keyFunc){
var mapping = {};
for (var i = 0; i < arr.length; i++) {
mapping[keyFunc(arr[i])] = arr[i];
}
return mapping;
}
这将返回一个对象映射8到具有key.id === 8
的对象。您的keyFunc
将是:
function keyFunc(element){
return element.key;
}
答案 4 :(得分:0)
为什么重新发明轮子?这里有很多类似的答案,所以我会分享一种不同的方法 - 到目前为止我最喜欢的方法。有一个很棒的库linq.js(独立和jQuery插件版本),它使搜索,过滤,排序等变得轻而易举。
var myElement = Enumerable.From(arr).FirstOrDefault(null, function(element) {
return element.key === 8;
});
在上面的示例中,返回与条件匹配的第一个元素。如果未找到任何内容,则返回null(第一个参数是要返回的默认值)。