获取嵌套地图的第n个元素

时间:2019-01-05 03:11:30

标签: function clojure

我想获取嵌套映射的第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=> 

有什么建议吗?

1 个答案:

答案 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]>

您可以使用keyval函数从MapEntry获取键和值:

(key (nth mapseq 3)) => :b
(val (nth mapvec 3)) => 2

P.S。您可以在using the spyxx function上方打印值及其类型。