javascript - JavaScript 是否将哈希表用于 Map 和 Set?
问题描述
我是一名 Python 开发人员,在 JavaScript 中迈出了第一步。
我开始使用Map和Set。它们似乎具有与dict
Python相同的 API set
,所以我假设它们是一个哈希表,我可以依靠 O(1) 查找时间。
但后来,出于好奇,我试图看看如果我在 Chrome 的控制台中执行此操作会发生什么:
new Set([new Set([1, 2, 3])])
会发生什么:
Set(1) {Set(3)}
JavaScript 愉快地创建了集合。怎么会这样?在 Python 中你会得到一个错误,因为你不能把一个可变项放在一个集合或一个字典中。为什么 JavaScript 允许它?
解决方案
考虑以下 JS 代码:
> m1 = new Map([['a', 1]])
Map { 'a' => 1 }
> m2 = new Map()
Map {}
> m2.set(m1, 3)
Map { Map { 'a' => 1 } => 3 }
> m2.get(m1)
3
但请注意,它是基于身份的散列,即===
,所以......
> m2.get(new Map([['a',1]]))
undefined
所以说真的,这张地图有多大用处?
请注意,这与 Python 的默认行为没有什么不同。用户定义类型的默认状态是可散列:
>>> class Foo: pass
...
>>> f0 = Foo()
>>> s = {f0}
>>> Foo() in s
False
>>> f0 in s
True
在 Python 中,默认情况下object.__eq__
会根据身份进行比较,所以上面的就可以了。但是,如果您 override __eq__
,默认情况下,__hash__
设置为None
并尝试使用基于散列的容器将失败:
>>> class Bar:
... def __init__(self, value):
... self.value = value
... def __eq__(self, other):
... return self.value == other.value
...
>>> b0 = Bar(0)
>>> b1 = Bar(2)
>>> {b0, b1}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'Bar'
在这一点上,您必须实现__hash__
与__eq__
推荐阅读
- visual-studio-code - 如何跨项目共享 .vscode/extensions.xml 文件?
- selenium - 如何使用 Selenium 在 Opera 中下载 PDF?
- javascript - React Hooks Find by ID 返回无法读取未定义的属性“参数”
- python - 如何生成网格图来填充颜色?
- python - 坐标系未在 holoviews 的 DynamicMap 中更新
- css - 尽管出现错误,为什么我的 VScode sass 编译器仍在编译?
- typescript - GraphQL 代码生成器 - Graphql 文档验证失败
- perl - 来自 OpenEdge 应用程序的 perl 脚本调用导致错误:无法查找符号 boot_DynaLoader
- java - 将地图值转换为 list<{specific type}>
- msbuild - 如何在 MSBuild 包目标之前执行某些操作?