隐藏PersistentHashMap的'get'函数

时间:2015-07-12 19:52:50

标签: clojure

我正在尝试使用我喜欢的一些集合和点阵理论概念来探索用关键术语标记的数据结构,例如“系统理论”或“互联网”。我想也许我可以扩展哈希映射的工作方式。我为我想要的行为编写了一些测试,然后我意识到我并不真正理解如何使用类型和协议来工作或工作。

这是个主意。我想按字符串集索引数据集合。例如,

(def data { #{"systems theory" "internet"} [1 2 3]
  #{"systems theory" "biology"} [4 5]
  #{"systems theory"} [6 7 8] })

免费,我得

(data #{"systems theory"})
;=> [6 7 8]

这很好。

但是能够做类似

的事情也很光滑
(data "biology")
;=> { #{"systems theory"} [4 5] }

当我想到这一点时,我认为告诉PersistentHashMap的get方法正常运行并不困难,除非要求它使用String作为键,在这种情况下,做任何事情获得新的数据结构是必要的。但是当编写代码时,我只是弄得一团糟,我实际上并不知道如何设计这个东西。

我有Fogus的 Clojure的喜悦的副本,我将阅读关于类型和协议以及扩展类型等的内容,看看我是否可以理解构建的方式和位置 - 在函数中定义和更改。但我也会喜欢暗示。

2 个答案:

答案 0 :(得分:2)

我不会创建新的专业地图实现,而是根据原始数据创建一个简单的索引图:

(def data {#{"systems theory" "internet"} [1 2 3]
           #{"systems theory" "biology"} [4 5]
           #{"systems theory"} [6 7 8] })

(def cats (->> data
               (map (fn [[cats val]]
                      (->> cats
                           (map (juxt identity #(hash-map (disj cats %) val)))
                           (into {}))))
               (apply merge)))

(get cats "internet")
;=> {#{"systems theory"} [1 2 3]}

(get cats "biology")
;=> {#{"systems theory"} [4 5]}

(get cats "systems theory")
;=> {#{"biology"} [4 5]}

如果您愿意,也可以合并它们:

(def full-index (merge data cats))

(get full-index "internet") ;=> {#{"systems theory"} [1 2 3]}
(get full-index #{"systems theory"}) ;=> [6 7 8]

如果您仍想创建专门的地图实现,您可能需要查看以下内容:

  • PersistenHashMap implementation

  • sorted.clj:" An Clojure"编写的Clojure排序集合的实现。 例如,请参阅the code for PersistentTreeMap 用于实现sorted-map

  • data.avl:"持久排序 带有日志时间排名查询的地图和集合"

  • data.priority-map: "优先级映射与有序映射非常相似,但是已排序 map生成按键排序的条目序列,优先级映射 生成按值排序的条目。"。也许代码更容易 比其他人理解。

如果你想保留哈希映射的语义(例如count应该返回原始映射计数加上新密钥计数的总和),这将变得很容易。您可能希望使用collection-check来测试您的实施。

答案 1 :(得分:1)

您所描述的内容可能是可能的,但我认为您最好只编写一个函数来筛选包含搜索字词的任何集合的列表。

此外,考虑您将要使用的访问模式,我怀疑将字符串作为键,并且集合中的文档ID可能更高效,更灵活。