在循环内使用 indexOf 是一个坏主意吗?

Posted

技术标签:

【中文标题】在循环内使用 indexOf 是一个坏主意吗?【英文标题】:Is it a bad idea to use indexOf inside loops? 【发布时间】:2017-01-20 16:05:45 【问题描述】:

我正在为一次技术面试学习大 O 表示法,然后我意识到 javascriptindexOf 方法可能具有 O(N) 的时间复杂度,因为它遍历数组的每个元素并返回找到它的索引。

我们还知道,O(n^2)(n 平方)的时间复杂度对于较大的数据并不是一个好的性能指标。

那么在循环内使用indexOf 是个坏主意吗?在 javascript 中,在循环中使用indexOf 方法的代码很常见,可能是为了衡量相等性或准备一些对象。

我们是否应该在必要时首选对象而不是数组,因为它们提供具有恒定时间性能 O(1) 的查找。

任何建议将不胜感激。

【问题讨论】:

【参考方案1】:

在循环内使用indexOf 可能是个坏主意,尤其是当您正在搜索的dataStructure 非常大时。 解决此问题的一种方法是拥有一个哈希表或字典,其中包含您可以在O(N) 时间生成的每个项目的索引,方法是循环遍历数据结构并在每次添加到数据结构时更新它。

如果你 push 在数据结构的末尾有一些东西,它将花费 O(1) 时间来更新这个表,最坏的情况是如果你将一些东西推到数据结构的开头,它将花费 O(N) .

在大多数情况下,这是值得的,因为获取索引将是 O(1) 时间。

【讨论】:

【参考方案2】:

说实话,tl;博士。但是,我对检查字符串中出现的各种方法进行了一些速度测试(如果这是您使用 indexOf 的目标。如果您实际上是在尝试获取匹配的位置,我个人不知道如何提供帮助你在那里)。我测试的方式是:

.includes() .match() .indexOf()

(还有.search().lastIndexOf()等变种,我没测试过)。

这是测试:

var test = 'test string';

console.time('match');
console.log(test.match(/string/));
console.timeEnd('match');

console.time('includes');
console.log(test.includes('string'));
console.timeEnd('includes');

console.time('indexOf');
console.log(test.indexOf('string') !== 0);
console.timeEnd('indexOf');

我知道它们不是循环,但向您展示它们的速度基本相同。老实说,每个人都做不同的事情,这取决于你的需要(你想用 RegEx 搜索吗?你需要预先兼容 ECMAScript 2015 吗?等等 - 我什至没有列出所有这些)是否真的有必要分析就这么多?

根据我的测试,有时indexOf() 会赢,有时其他一个会赢。

【讨论】:

您提到的所有上述解决方案可能会提供相同的性能,因为输入非常非常小。我主要关心的是数据量要大得多。

以上是关于在循环内使用 indexOf 是一个坏主意吗?的主要内容,如果未能解决你的问题,请参考以下文章

可以以有效的方式在模拟循环内进行多线程吗?

扩展std :: vector是个好主意吗?

通过 express req 参数传递解码的 jwt 数据是个好主意吗?

GD32的RTC出问题了,有主意吗?

在HomePage控制器上何处发送救援?

原声js常用的一些数组查询方法如删除数组内指定项Indexof 配合使用