在Javascript ES6 Map中如何获取或设置元素?

5

在Javascript的Map中是否可能在一个步骤中查找或添加元素?

我想要在一个步骤中完成以下操作(避免两次查找正确的键位置):

// get the value if the key exists, set a default value otherwise
let aValue = aMap.get(aKey)
if(aValue == null) {
    aMap.set(aKey, aDefaultValue)
}

我希望只搜索一次密钥。

在c++中,可以使用std::map::insert()std::map::lower_bound()

在javascript中,代码可以如下所示:

let iterator = aMap.getPosition(aKey)
let aValue = aMap.getValue(iterator)
if(aValue == null)
{
    aMap.setWithHint(aKey, aValue, iterator)
}

或者

let aValue = aMap.getOrSet(aKey, aDefaultValue) 

我认为这是不可能的,但我想确定我是正确的。同时,我也想知道为什么它是一个重要的功能却不可能实现。


我理解你的意思是你担心在代码示例中 aKey 需要被查找两次? - nils
是的,这就是问题。 - arthur.sw
1
一般来说,在JavaScript中,你不必担心这些微小的优化问题。现代JavaScript引擎在处理这些方面做得相当好。此外,据我所知,使用映射无法防止这种情况的发生。 - nils
2个回答

3

查找必须发生,如果您避免它也无关紧要,至少在引擎优化得更多之前是如此。

但是Map.has是一种更好的解决方案,应该比Map.get()快一点。例如:

myMap.has(myKey) ? true : myMap.set(myKey, myValue)

性能在这个级别上应该不重要,除非您是Google规模的公司。但如果它是一个严重的瓶颈,那么数组仍然比Map/Set更快,未来也将是如此。


0
我个人最终将我的Map更改为一个简单的Object。这样可以编写一个reduce函数(将条目分组为Set的Map),如下所示:
.reduce((a, [k, v]) => (a[k] = a[k] || new Set()).add(v) ? a : a, {})

用 Map 应该已经变成了

.reduce((a, [k, v]) => (a.has(k) ? a : a.set(k, new Set())).get(k).add(v) ? a : a, new Map())

对于这个目的来说,感觉有点繁琐。

如果支持类似于这样的东西,我同意这会是理想的:

.reduce((a, [k, v]) => a.getOrSet(k, new Set()).add(v) ? a : a, new Map())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接