阴影PersistentHashMap的“获取”功能

问题描述:

我试图想出探索已经被打上了关键条款数据,如“系统论”或“互联网”的数据结构,使用一些设置和晶格理论概念,我喜欢。我想也许我可以扩展散列图的工作方式。我为我想要的行为写了一些测试,然后我意识到我并不真正懂得如何使用类型和协议来工作或做什么工作。阴影PersistentHashMap的“获取”功能

这是主意。我想通过一组字符串来索引一组数据。例如,

(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方法来充当正常的,除非它被要求使用一个字符串作为关键字,在这种情况下,尽一切可能获得新的数据结构。但是当编写代码时,我只是一团糟,实际上我不知道如何设计这个东西。

我有我的Fogus的副本Clojure的欢乐我将阅读关于类型和协议以及扩展类型等信息,看看我是否可以理解如何以及在何处定义内置函数并改变了。但我也喜欢暗示。

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

(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: “一个 实现Clojure的Clojure编写的有序集合”。 例如,见the code for PersistentTreeMap 这是用来实现sorted-map

  • data.avl:“持续进行排序 地图和套与数时间排名查询”

  • data.priority-map: “优先级的地图是非常相似的一个有排序的映射,但排序的映射产生按键排序的条目序列,优先映射 产生按值排序的条目“。也许代码比其他代码更容易理解 。

,如果你想保持一个哈希地图的语义这不会是容易的(例如count应该回到原来的地图数的总和加上新密钥计数)。您可能需要使用collection-check来测试您的实施。

+0

收集检查是一个很好的建议。我试图进行测试驱动,这看起来像是一种避免在创建新数据结构时失去功能的方法。 – tom

你描述什么是可能的,但我认为你会更好只是写一个函数,通过该列表,您搜寻字词的任何设置进行过滤。

另外,还要考虑你将要使用的访问模式,我怀疑有一组字符串作为键和文档ID可以被更高效,更灵活。

+0

我认为“这不是正确的做法”是正确的答案。我想定义围绕“集合”和“元素”而不是“集合”和“java.lang.String”的概念的函数,所以用get来摆弄是处于错误抽象层次的逻辑。 – tom