function contains(arr, obj) {
const stringifiedObj = JSON.stringify(obj); // Cache our object to not call `JSON.stringify` on every iteration
return arr.some(item => JSON.stringify(item) === stringifiedObj);
}
用法:
contains([{a: 1}, {a: 2}], {a: 1}); // true
ie6+解决方案:
function contains(arr, obj) {
var stringifiedObj = JSON.stringify(obj)
return arr.some(function (item) {
return JSON.stringify(item) === stringifiedObj;
});
}
// .some polyfill, not needed for IE9+
if (!('some' in Array.prototype)) {
Array.prototype.some = function (tester, that /*opt*/) {
for (var i = 0, n = this.length; i < n; i++) {
if (i in this && tester.call(that, this[i], i, this)) return true;
} return false;
};
}
21条答案
按热度按时间cs7cruho1#
先开箱思考一下,如果您多次进行此调用,那么使用关联数组和Map来使用哈希函数进行查找要高效得多。
https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/map
b4wnujal2#
使用lodash的一些功能。
它简洁、准确,并具有强大的跨平台支持。
被接受的答案甚至不符合要求。
要求:推荐最简洁有效的方法来确定javascript数组是否包含对象。
接受的答复:
我的建议是:
笔记:
$.Inaray w
aoyhnmkz3#
适用于所有现代浏览器的解决方案:
用法:
ie6+解决方案:
用法:
为什么要使用json.stringify?
Array.indexOf
及Array.includes
(以及这里的大多数答案)仅通过参考而不是价值进行比较。奖金
非优化es6单衬套:
注意:如果键的顺序相同,则按值比较对象的效果会更好,因此为了安全起见,您可以先使用如下包对键进行排序:https://www.npmjs.com/package/sort-keys
更新
contains
具有性能优化功能。谢谢你指出这一点。egmofgnx4#
我们使用此代码段(用于对象、数组和字符串):
用法:
pes8fvy95#
如果您反复检查数组中是否存在对象,您可能应该查看
通过在数组中执行插入排序(将新对象放在正确的位置),始终保持数组的排序
将更新对象设为删除+排序插入操作,然后
在数据库中使用二进制搜索查找
contains(a, obj)
.chhkpiq46#
如果找到,则返回数组索引;如果未找到,则返回-1
kupeojn67#
如果您使用的是javascript 1.6或更高版本(firefox 1.5或更高版本),则可以使用array.indexof。否则,我认为您将得到类似于原始代码的东西。
kknvjkwl8#
希望更快的双向
indexOf
/lastIndexOf
可供替代的2015
虽然新方法includes非常好,但目前支持率基本为零。
很长一段时间以来,我一直在考虑替换慢速indexof/lastindexof函数的方法。
我们已经找到了一种有效的方法,看看上面的答案。从那些我选择的
contains
@damir zekic发布的函数应该是最快的函数。但它也指出,这些基准是从2008年开始的,因此已经过时。我也更喜欢
while
结束for
,但不是因为特定的原因,我用for循环结束了函数的编写。这也可以通过一个while --
.我很好奇,如果在执行迭代时检查数组的两侧,迭代是否会慢得多。显然不是,所以这个函数比最受欢迎的函数快两倍左右。显然它也比本地的快。这是在现实环境中进行的,在现实环境中,您永远不知道要搜索的值是在数组的开头还是结尾。
当你知道你刚刚用一个值推送了一个数组时,使用lastindexof可能是最好的解决方案,但是如果你必须遍历大数组,结果可能无处不在,这可能是一个使事情更快的解决方案。
双向索引of/lastindexof
性能测试
http://jsperf.com/bidirectionalindexof
作为测试,我创建了一个包含100k条目的数组。
三个查询:在开始时,在中间和在数组的末尾。
我希望您也会觉得这很有趣,并测试性能。
注意:如您所见,我稍微修改了
contains
函数来反映indexof和lastindexof输出(因此基本上true
和index
及false
具有-1
). 这不应该伤害它。阵列原型变型
该函数还可以很容易地修改为返回true或false,甚至返回对象、字符串或其他内容。
这里是
while
变体:这怎么可能?
我认为在数组中获得反射索引的简单计算非常简单,比实际循环迭代快两倍。
下面是一个复杂的示例,每个迭代执行三次检查,但这只有在计算时间较长的情况下才可能实现,这会导致代码速度减慢。
http://jsperf.com/bidirectionalindexof/2
wi3ka0sx9#
array.prototype.some()在第5版中添加到ecma-262标准中
ubbxdtey10#
我使用以下方法:
kxxlusnw11#
演出
今天是2020.01.07,我在macos highsierra 10.13.6上对chrome v78.0.0、safari v13.0.4和firefox v71.0.0进行测试,测试了15个选定的解决方案。结论
基于
JSON
,Set
令人惊讶的是find
(k,n,o)是所有浏览器中速度最慢的es6
includes
(f) 只有在铬上才快速基于
for
(c、d)及indexOf
(g,h)在大小阵列上的所有浏览器上都非常快,因此它们可能是高效解决方案的最佳选择在循环过程中索引减少的解决方案(b)速度较慢,可能是因为cpu缓存的工作方式。
当搜索的元素位于数组长度的66%位置时,我还对大数组运行了测试,并基于
for
(c,d,e)给出了类似的结果(约630次/秒-但safari和firefox上的e比c和d慢10-20%)结果
细节
我执行了两个测试用例:对于包含10个元素的数组,以及包含1百万个元素的数组。在这两种情况下,我们都将搜索的元素放在数组中间。
小数组-10个元素
您可以在这里的机器上执行测试
阵列大-1.000.000个元素
您可以在这里的机器上执行测试
9q78igpj12#
一艘班轮:
thtygnil13#
扩展javascript
Array
对象是一个非常糟糕的主意,因为您将新属性(您的自定义方法)引入到for-in
可以中断现有脚本的循环。几年前,原型库的作者不得不重新设计他们的库实现,以删除这种东西。如果您不需要担心与页面上运行的其他javascript的兼容性,那么就去做吧,否则,我建议使用更笨拙但更安全的独立函数解决方案。
yb3bgrhw14#
使用:
ebdffaop15#
下面是与javascript 1.6兼容的
Array.indexOf
: