【问题标题】:How to construct an ordered Map as a persistent data structure?如何将有序 Map 构造为持久数据结构?
【发布时间】:2020-04-08 19:04:43
【问题描述】:

我有一个基于散列数组映射树的持久数据结构hamt,这是一些更具体的持久数据结构的基础,例如不可变数组。它提供了一个相当简单的 API:

const hamtDel = (hamt, props, k) => {/* implementation */}
const hamtGet = (hamt, k) => {/* implementation */}
const hamtSet = (hamt, props, k, v) => {/* implementation */}
const hamtEmpty = () => {/* implementation */} // creates an empty hamt

hamtkv 是不言自明的。 props 只是将任意属性添加到新生成的 hamt 对象的一种方式。例如,不可变数组具有额外的lengthoffset 属性,以允许高效的conssnoc 操作。

hamt 本身基本上是一个无序的 Map。由于有序地图在 Javascript 中很常见,我尝试基于hamt 实现一个。然而,事实证明这非常困难。为了跟踪插入顺序,我需要一个 hamt A 用于实际的键/值对,以及一个保存从插入数到相应键 B 的映射。

鉴于这两种结构,我可以像往常一样访问A 的元素,并通过检索B 持有的插入顺序来遍历A。但是,当我想删除A 中的元素时,我还需要删除B 中的元素。 B 中的键是插入次数。这意味着在最坏的情况下,我必须遍历整个 B 结构才能找到相应的键。

第三个hamtB 的键/值对倒置可以缓解此问题,但最终使用三个hamts 只是为了获得有序映射似乎是一个糟糕的设计选择。

我很确定这个问题是众所周知的,并且有可靠的解决方案来解决它。由于缺乏正确的术语,我还没有发现任何有用的东西。非常欢迎就此事提供帮助。

【问题讨论】:

  • 你有一些代码吗?还有一些例子?
  • 实现有序字典 AFAIK 的常用方法是存储无序字典和按插入顺序排列的值数组。由于您可以控制实现,因此您可以将 HAMT 与持久向量结合起来,两者的元素都只指向包含的值。
  • @phipsgabler 谢谢,我会试试的。

标签: javascript functional-programming tree trie


【解决方案1】:

在 Scala 和 Kotlin 中有一些实现可供研究。

首先是 scala 的 VectorMap (https://github.com/scala/scala/blob/v2.13.3/src/library/scala/collection/immutable/VectorMap.scala)

它使用压缩哈希数组映射特里树(也称为 CHAMP)(类似于 HAMT 的不可变哈希图)与作为基数平衡树的向量的组合来按顺序存储键。

接下来是 scala 的 TreeSeqMap (https://github.com/scala/scala/blob/v2.13.3/src/library/scala/collection/immutable/TreeSeqMap.scala)

这使用与 VectorMap 相同的 CHAMP 哈希图,但与专用的 Trie-Map 一起使用,其中键类似于整数索引,值是有序映射的实际键。

接下来是我几个月前写的这个提议的LinkedHashMap,它与支持可变双链表的 LinkedHashMap 非常相似,但将链表拆分成段以实现更好的持久更新:https://github.com/scala/scala/pull/8644/files

最后是 Kotlin 的 OrderedMap 这里:https://github.com/Kotlin/kotlinx.collections.immutable/blob/master/core/commonMain/src/implementations/persistentOrderedMap/PersistentOrderedMap.kt 这与之前的实现基本相同,只是 Link 段的长度都是 1(即每个键值都是它自己的段,或者换句话说'不是分段,而只是通过键而不是指针指向前后的单个元素)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多