Javascript 检查数组中是否存在某些内容的最佳方法是什么?
我正在创建的项目涉及到多次搜索一个数组,我意识到如果我不以最理想的方式进行搜索,我可能会看到服务器性能问题 我想知道在数组中查找值的服务器密集度最低的方法是什么,非常感谢您的帮助Javascript 检查数组中是否存在某些内容的最佳方法是什么?,javascript,Javascript,我正在创建的项目涉及到多次搜索一个数组,我意识到如果我不以最理想的方式进行搜索,我可能会看到服务器性能问题 我想知道在数组中查找值的服务器密集度最低的方法是什么,非常感谢您的帮助 我在这个网站上看到一些人回答了这个问题,但答案有好有坏,一些人说基本的for循环最好,另一些人说indexOf和findIndex性能更好,但不确定哪一个最好,或者是否有不同的选择。在长度数组n中搜索的时间复杂度是O(n)而使用a将使您的时间复杂度达到O(1),因为您不需要迭代映射以了解其中是否存在特定元素。您可以使用
我在这个网站上看到一些人回答了这个问题,但答案有好有坏,一些人说基本的for循环最好,另一些人说indexOf和findIndex性能更好,但不确定哪一个最好,或者是否有不同的选择。在长度数组
n
中搜索的时间复杂度是O(n)
而使用a将使您的时间复杂度达到O(1)
,因为您不需要迭代映射
以了解其中是否存在特定元素。您可以使用其键
获取元素
如果元素存在,它将在O(1)
时间内返回,否则您将得到undefined
表示您搜索的元素在映射中不存在
因此,在您的情况下,最好使用Map
而不是数组。即使是通过列表进行的最优化搜索,运行时的复杂性也为O(n)
。基本for循环是最快的,因为您可以使它在第一次出现时终止。搜索对象时,事情会变得稍微有趣一些
function arrayHasObj(obj, list) {
var i = list.length;
while (i--) {
if (JSON.stringify(list[i]) === JSON.stringify(obj)) {
return true;
}
return false;
};
}
这里的while
循环显然是O(n)
,但我们还需要考虑将对象序列化为JSON。这不符合任何标准的时间复杂性分析。如果有人能称一下,请称一下
通常,不需要通过单个数组优化搜索。在您的算法中需要进行一些更大的优化,或者如果您真正使用的是一个大型数据集,那么您应该使用它来查询数据库
编辑:
显然,一本词典/一套词典有它的优点。OP特别询问数组。为什么使用数组而不是集合?原生JS总是最好的:yourArray.indexOf(“value”)>-1比较array
和Set
的复杂性是O(N)对O(1)。@Camille你应该告诉then;)还有一个节点,即服务器端JS。@Camille我要说的是使用一个集合-如果你没有键值关系,而数组大多没有键值关系,映射就没有真正的好处。除非索引很重要,但仅仅是搜索就有点可疑。)@VLAZ但如果它们是我放在一个集合中的对象,它就不起作用了,对吗?当我测试它时,似乎如果我在集合中请求相同的对象,但我没有,那么集合中的.has方法将返回falsesure@Buckets取决于你在搜索什么。如果是对象,则需要原始引用,但Array#indexOf
和Array#includes
也是如此。既然您提到了这些,我假设您正在搜索基本体或现有对象。如果您需要按参数进行搜索,这不会反映在您的问题中。@这就是为什么我建议使用Map
而不是Set
。在Map
中,在Map
中添加对象时,可以提供唯一的键。当您需要搜索任何对象时,只需使用其键
“即使是通过列表进行的最优化搜索,其运行时复杂性也为O(n)”???排序后的列表可以在O(log(n))
中轻松地进行二进制搜索。如果您使用哈希结构维护一个查找表,那么您的搜索将是O(1)
,具有良好的哈希算法和bucketing。我们不能假设列表已排序,它从未指定。使用标准的快速排序对列表进行排序会添加一个运行时O(n*log(n))
。现在您正在进行一个假设-列表可能已经排序或是静态的。如果它没有改变,那么执行一次O(n*log(n))
来加速许多查找是可以忽略的。我对任何搜索都是O(n)
的说法提出质疑。当然,它添加了假设,但也需要假设来声明其他情况。这将依赖于实现,但速度较慢,因为它需要解析。而且,它也不可靠-JSON.stringify({a:1,b:2})==JSON.stringify({b:2,a:1})
可能工作,也可能不工作,这取决于平台的情况,很可能不工作JSON.stringify({a:1,b:2})==JSON.stringify({a:1,b:2})
的成功几率较高,但仍然依赖于平台。问题是JS不支持密钥的一致排序,而且这并不是在每个平台上都实现的。即使是这样,您也可能陷入一个陷阱:JSON.stringify({a:1,1:true})==JSON.stringify(1:true,a:1)
在兼容的平台上,因为数字键会放在前面。此外,您还存在一个问题,即仅限于JSON可序列化内容—函数和(非基本)对象将具有不同的表示形式,未定义的
在JSON中不存在,并且不支持符号键。所以,这不是一个完美的解决方案。