2017-01-23 96 views
1

我有一组的HashMap的(或一个HashSet,包含HashMap数组)象下面这样:如何将数据添加到Clojure中的哈希集?

(def mydata #{{:rank 2 :page 1 :group "fish"} 
       {:rank 1 :page 1 :group "mammal"} 
       {:rank 3 :page 2 :group "bird"}}) 

,我有一个新的HashMap是这样的:

{:group "mammal" :name "lion" :score 566} 

我想基本上做什么是新的HashMap的数据排序合并到上述阵列,所以它看起来像这样(“组”是连接键):

#{{:rank 2 :page 1 :group "fish"} 
    {:rank 1 :page 1 :group "mammal" :name "lion" :score 566} 
    {:rank 3 :page 2 :group "bird"}} 

我的想法是先找到在索引数组是1(基于零),然后使用与给定的新散列映射相关联的函数,因此'group'被忽略或保持不变,'name'和'score'被添加。

首先,我需要找到一种方法来获取该索引,但这是我现在卡住的地方。

有没有简单和容易的方法来做到这一点?完成的数据将被转换为json。我不确定是否建立一个像这样的hashmaps数组是一种在Clojure中创建一些json数据的正确方法。至少,将一组hashmaps传递给json库现在可以生成一个数组,以json格式提供数据集,但请提供一些建议,如果我以错误的方式行事。)

+0

您的数据结构只允许每组中的一只动物。是这样吗? – Thumbnail

+0

是的,就是这样。它就像RDB模式中的1:1连接键。 – gini09

回答

2

首先哈希集不给你任何的利润在这个用例(任何顺序都行,任何序列将被转换成JSON数组,根据我了解Clojure中的JSON库)

但是您所描述的操作类型相当频繁,并且/或者集合可能很大,每次遍历整个集合都会非常昂贵。我会重新格式化您的数据,按组索引的地图:

(def mydata {"fish" {:rank 2 :page 1 :group "fish"} 
      "mammal" {:rank 1 :page 1 :group "mammal"} 
      "bird" {:rank 3 :page 2 :group "bird"}}) 

,然后更新它是这样的:

(defn update-animal [animal data] 
    (update data (:group animal) merge animal)) 


user> (update-animal {:group "mammal" :name "lion" :score 566} mydata) 
;;{"fish" {:rank 2, :page 1, :group "fish"}, 
;; "mammal" {:rank 1, :page 1, :group "mammal", :name "lion", :score 566}, 
;; "bird" {:rank 3, :page 2, :group "bird"}} 

,当你需要将其转换为JSON,你只需要值序列: (to-json (vals data))

0

集合没有索引。你可以迭代它的所有元素,如果任何一个匹配新的hashmap,那么用一个合并的hasmap(现有的元素和新的元素)替换它。最后将结果转换为一个集合。

(defn update-set 
    [baseset elem] 
    (set (map #(if (= (:group elem) (:group %)) 
       (merge elem %) 
       %1) 
      baseset))) 


(def mydata #{{:rank 2 :page 1 :group "fish"} 
      {:rank 1 :page 1 :group "mammal"} 
      {:rank 3 :page 2 :group "bird"}}) 

(update-set mydata {:group "mammal" :name "lion" :score 566})