更新:目标不仅仅是冻结哈希表(或数组),而是要实现一个高效的更新操作——更新不可变哈希表应该返回一个新的不可变哈希表。它应该比“克隆原始数据并更新”更有效率。
本机JS类型的更新复杂度大约为O(1),通过克隆的复杂度将为O(n),使用特殊的不可变数据结构(我所要求的)将为0(log(n))。
更新2:JavaScript已经有Array / Hash:
是的,但它们是可变的,我需要类似但不可变的东西,基本上可以通过克隆
hash2 = hash1.clone(); hash2[key] = value
来完成,但这样做非常低效,有算法可以使其非常高效,而不使用clone
。hash1 = {}
hash2 = hash1.set('key', 'value2')
hash3 = hash1.set('key', 'value3)
console.log(hash1) // => {}
console.log(hash2) // => {key: 'value2'}
console.log(hash3) // => {key: 'value3'}
解决方案:
这不是一个不可变哈希的实现,而更像是我当前问题的一种hack方法,也许它也能帮助其他人。
再说一些为什么我需要不可变数据结构的原因 - 我使用Node.js和类似于内存数据库的东西。一个请求可以读取数据库,另一个请求可以更新它 - 更新可能需要很长时间(调用远程服务) - 所以我不能阻塞所有读进程并等待更新完成,而且更新可能会失败,数据库应该回滚。所以我需要以某种方式隔离(ACID)内存数据库的读写操作。
这就是为什么我需要不可变数组和哈希表 - 以实现类似MVCC的东西。但似乎有一种更简单的方法来做到这一点。更新操作不是直接更新数据库 - 而是将更改记录到数据库中(但不直接执行),例如“将42添加到数组db.someArray中”的形式。
最终 - 更新操作的产物将是一系列这样的更改命令的数组,因为它可以很快地应用 - 我们可以阻止数据库应用它。
但是,如果在JavaScript中有不可变数据结构的实现,那还是很有趣的,所以我会让这个问题保持开放状态。
java.util.Vector
这样的索引集合? - eh9Object.preventExtensions()
、Object.seal()
和Object.freeze()
吗? - Šime Vidas