我想获取嵌套映射的第n个元素,但是找不到合适的命令并且出现了错误。我需要像first
函数那样的东西:
boot.user=> (def db2 @main/database)
#'boot.user/db2
boot.user=> (def ims (get-in db2 [kl :items]))
#'boot.user/ims
boot.user=> ims
{"i15059" {:name "ESS1", :done? false}, "i15064" {:name "ESS2", :done? false}, "i15114" {:name "ESS3", :done? false}, "i15121" {:name "ESS3", :done? false}}
boot.user=> (first ims)
["i15059" {:name "ESS1", :done? false}]
boot.user=> (nth ims 1)
java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap
boot.user=>
有什么建议吗?
答案 0 :(得分:3)
地图是无序的(除非您显式创建了sorted-map
)。当您获得地图条目(例如for
循环或first
)时,Clojure会在地图上静默调用seq
以获取MapEntry
的“列表式”序列项目:
(def mappy {:c 3 :d 4 :a 1 :b 2 })
mappy => {:c 3, :d 4, :a 1, :b 2}
(seq mappy) => ([:c 3] [:d 4] [:a 1] [:b 2])
(vec mappy) => [[:c 3] [:d 4] [:a 1] [:b 2]]
(first mappy) => [:c 3]
请注意,seq
的打印方式类似于列表,但不是。 MapEntry的打印效果像矢量,但不是。
(seq mappy) => <#clojure.lang.PersistentArrayMap$Seq ([:c 3] [:d 4] [:a 1] [:b 2])>
(first mappy) => <#clojure.lang.MapEntry [:c 3]>
一旦有了一些顺序对象(向量,列表或序列),就可以使用nth
一次获得一个项目:
(let [mapseq (seq mappy)
mapvec (vec mappy) ]
(nth mapseq 3) => [:b 2]
(nth mapvec 3) => [:b 2]
但是请注意,返回的项目仍然是MapEntry
,而不是2向量。
(nth mapseq 3) => <#clojure.lang.MapEntry [:b 2]>
(nth mapvec 3) => <#clojure.lang.MapEntry [:b 2]>
您可以使用key
和val
函数从MapEntry获取键和值:
(key (nth mapseq 3)) => :b
(val (nth mapvec 3)) => 2
P.S。您可以在using the spyxx
function上方打印值及其类型。