Clojure:转换为哈希映射后不是整个集合

Clojure:转换为哈希映射后不是整个集合,clojure,hashmap,Clojure,Hashmap,我正在探索Clojure这个激动人心的世界,但我被这一点阻止了。。。 我有两个向量,长度不同,存储在变量中 (def lst1 ["name" "surname" "age"]) (def lst2 ["Jimi" "Hendrix" "28" "Sam" "Cooke" "33" "Buddy" "Holly" "23"]) 我想将它们交错并获得一个映射,其中包含第一个列表中的键和第二个列表中的值,如下所示: {"name" "Jimi" , "surname" "Hendrix" , "

我正在探索Clojure这个激动人心的世界,但我被这一点阻止了。。。 我有两个向量,长度不同,存储在变量中

(def lst1 ["name" "surname" "age"]) 
(def lst2 ["Jimi" "Hendrix" "28" "Sam" "Cooke" "33" "Buddy" "Holly" "23"])
我想将它们交错并获得一个映射,其中包含第一个列表中的键和第二个列表中的值,如下所示:

{"name" "Jimi" , "surname" "Hendrix" , "age" "28" , 
 "name" "Sam" , "surname" "Cooke" , "age" "33" ... }
即使使用正确的键,以下解决方案也可以:

{:name "Jimi" , :surname "Hendrix" , :age" "28" , ... }
我可以使用Medley库中的interleave all函数,然后应用哈希映射fn:

(apply hash-map 
    (vec (interleave-all (flatten (repeat 3 lst1)) lst2)))

=> {"age" "23", "name" "Buddy", "surname" "Holly"}
但只返回最后一个音乐家。此持久哈希映射没有顺序,但不是点


后来我尝试将键和值配对,也许是为了将来可能使用
assoc
,谁知道呢

(map vector
       (for [numMusicians (range 0 3) , keys (range 0 3)] (-> lst1 (nth keys) (keyword)))
       (for [values (range 0 9)] (-> lst2 (nth values) (str)))
       )
返回一个包含成对向量和正确关键字的惰性序列

=> ([:name "Jimi"] [:surname "Hendrix"] [:age "28"] [:name "Sam"] ...)
现在我想尝试
进入应该返回的

一个新的coll,由to coll和from coll的所有项组成 连体的

但是,再一次:

=> {:name "Buddy", :surname "Holly", :age "23"}
只是最后一个音乐家,这次是在持久数组映射中。 我想要一张有我所有死去音乐家的地图。有人知道我错在哪里

编辑:

谢谢你们!以这种方式管理fn:

(use 'clojure.set)
(->> (partition 3 lst2) (map #(zipmap % lst1)) (map map-invert))

=> ({"name" "Jimi", "surname" "Hendrix", "age" "28"} {"name" "Sam", "surname" "Cooke", "age" "33"} {"name" "Buddy", "surname" "Holly", "age" "23"})

尽管您需要以下表单:

{"name" "Jimi" , "surname" "Hendrix" , "age" "28" , 
 "name" "Sam" , "surname" "Cooke" , "age" "33" ... }
这是不允许的,因为关键点发生碰撞。不能多次将
“name”
作为键添加。键在地图中应该是唯一的

但您可以使用以下代码构建地图列表:

user=> (->> (map (fn [ks vs] (interleave ks vs)) (repeat 3 lst1) (partition 3 lst2))
            (map #(apply hash-map %)))

({"age" "28", "name" "Jimi", "surname" "Hendrix"} {"age" "33", "name" "Sam", "surname" "Cooke"} {"age" "23", "name" "Buddy", "surname" "Holly"})
更新 @status203使用
zipmap
的解决方案看起来更好

user=> (->> (partition 3 lst2)
            (map #(zipmap lst1 %)))

({"age" "28", "surname" "Hendrix", "name" "Jimi"} {"age" "33", "surname" "Cooke", "name" "Sam"} {"age" "23", "surname" "Holly", "name" "Buddy"})

每个键在地图中只能存在一次。因此,后面的值将覆盖前面的值

要获得每位艺人的地图列表,您可以执行以下操作:

(def lst1 ["name" "surname" "age"]) 
(def lst2 ["Jimi" "Hendrix" "28" "Sam" "Cooke" "33" "Buddy" "Holly" "23"])

(->> (partition 3 lst2) ; Split out the seperate people
     (map (fn [artist-seq] (zipmap lst1 artist-seq)))) ; Use zipmap to connect the keys and values.

这应该适用于任何数量的人,只要所有的值都存在,顺序正确

是的。。。就这样!我相信VAL的独特性。非常感谢ntalbs向我解释了它们的正确用法!是的,zipmap绝对是一个更优雅的解决方案。如果我将其转换为json,我只需反转映射(但不是k和v的顺序)。非常感谢。看看这个:调用后(使用'clojure.set:(映射映射反转(->>(分区3lst2)(映射#(zipmap%lst1)))
(def lst1 ["name" "surname" "age"]) 
(def lst2 ["Jimi" "Hendrix" "28" "Sam" "Cooke" "33" "Buddy" "Holly" "23"])

(->> (partition 3 lst2) ; Split out the seperate people
     (map (fn [artist-seq] (zipmap lst1 artist-seq)))) ; Use zipmap to connect the keys and values.