javascript中的IndexOf方法比迭代数组更有效吗?

时间:2015-12-17 13:54:31

标签: javascript arrays performance mongodb indexof

我有一个JSON对象数组,我想找到具有某个属性的对象。我知道这可能看起来像一个重复的问题,但请继续,因为我认为它与以前的问题略有不同。

我工作的人建议使用IndexOf,这让我思考。有什么类似于mongo中的$ elemMatch功能吗?是否有一些命令基本上用伪代码表示“从这个数组中获取具有此属性的对象”?通过迭代,我觉得psuedo-code说“看看这个数组中的第一个对象。如果这个对象有这个属性,给我这个对象。如果没有,看看这个数组中的第二个对象..... “

我理解如何像我朋友建议的那样使用IndexOf,但是我想的越多,我开始认为IndexOf方法可能是更少的代码行,但它最终不必遍历对象中的数组找到我需要的索引?所以如果我想用这个属性对对象做一些事情,并且我使用方法IndexOf来获取索引,那么我会引用像myArray [indexFromIndexOfMethod]这样的对象,然后相应地修改它,对吗?所以,如果javascript迭代数组本身来执行IndexOf方法,为什么我不编写自己的迭代并保存一个步骤?现在,如果IndexOf方法使用更有效的方法来定位数组元素,而不是迭代并检查每个元素,那么使用它对我来说是有意义的。否则,如果您可以通过简单的迭代实现相同的结果,那么使用IndexOf方法是没有意义的。

2 个答案:

答案 0 :(得分:4)

Array.prototype.indexOf也只是遍历数组并返回具有匹配值的第一个索引。你可以用循环做同样的事情。 可能或者可能不会比for循环略快,因为indexOf可以在本机代码中实现,并且与for循环的优化方式不同,但是没有根本的区别。

如果经常需要尽快访问特定值,则值得在对象中使用该值对其进行索引。这意味着,如果您想经常通过其属性.foo找到特定对象,请执行以下操作:

var byFoo = {}
for (var i = 0; i < myArray.length; i++) {
    byFoo[myArray[i].foo] = myArray[i];
}

然后,您可以使用byFoo['baz']进行即时访问。

当然,这会产生额外的开销,可能会将这些索引保存在多个副本中,但它会加快阵列访问的速度。你需要权衡利弊。

答案 1 :(得分:1)

indexOf如果它们是真实对象,就不会在对象上工作,因为即使它们具有相同的属性值,两个对象也会彼此不同,因此你不能使用真实对象作为indexOf的输入。

只有当JSON仍然是未解析的字符串时它才会起作用,那么它才是最有效的方法。

因此,如果我必须直接引用对象,我倾向于使用的解决方案是创建包含每个对象的索引的引用,或者只使用对象本身而不是数组来存储数据对象,并且具有唯一标识符,如数据对象的id,作为密钥。

// This will fail:
var data = [
    {
        'id' : 1,
        'value' : 'myDataForObj1'
    },
    {
        'id' : 2,
        'value' : 'myDataForObj2'
    }
];

data.indexOf({
    'id' : 2,
    'value' : 'myDataForObj2'   
}); // return -1, as in, not found.


// This will work:
var data = [
    '{"id":1,"value":"myDataForObj1"}',
    '{"id":2,"value":"myDataForObj2"}'
];

data.indexOf('{"id":2,"value":"myDataForObj2"}'); // return 1, as in the second element in the array.

// This is what I usually use:
var data = {
    'id1' :     {
        'id' : 1,
        'value' : 'myDataForObj1'
    },
    'id2' : {
        'id' : 2,
        'value' : 'myDataForObj2'
    }
};

data['id2'].value = 'newValue';

你必须在某种程度上引用你想要直接访问的所有内容,所以如果你想能够在任何对象中找到任何值,那么对于有很多的对象来说,循环可能会更容易实现属性。

因此,我已经养成了总是有一些“身份”的习惯。与我必须操纵的数据相关联。例如,最终用户单击表中的一行来编辑它。我确保该行有一个数据属性,该属性引用模型中数据所具有的id,它与后端中的id相同。在大多数情况下,这种设计消除了迭代数据存储的需要。