javascript 中的 IndexOf 方法是否比遍历数组更有效?

Is the IndexOf method in javascript more efficient than iterating through an array?

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

一个和我一起工作的人建议使用 IndexOf,这让我开始思考。 mongo 中是否有类似于 $elemMatch 功能的东西?是否有一些命令基本上用伪代码表示 "get me the object with this property from this array"?随着迭代,我觉得伪代码说 "look at the first object in this array. If this object has this property, get me this object. If not, look at the second object in this array....."

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

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' 与我必须处理的数据相关联的习惯。例如,最终用户单击 table 中的一行进行编辑。我将确保该行有一个数据属性,该属性引用数据在模型中的 id,该 id 与它在后端的 id 相同。在大多数情况下,这种设计消除了迭代数据存储的需要。

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

如果您经常 需要尽快访问特定值,则值得在对象中通过该值对它们进行索引。意思是,如果您想经常通过 属性 .foo 查找特定对象,请执行以下操作:

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

这样您就可以使用 byFoo['baz'] 进行即时访问。

当然,这可能会增加维护这些索引的多个副本的开销,但它会大大加快数组访问速度。你需要权衡利弊。