显然get-in
不适用于'()
列表,因为它们不是关联数据结构。这对于API以及从大型列表的性能角度来说是有意义的。从我作为用户的角度来看,仍然可以使用此功能来探索repl中的一些小测试数据。例如,我希望能够:
(-> '({:a ("zero" 0)} {:a ("one" 1)} {:a ("two" 2)})
(get-in [1 :a 0]))
=> "one"
还有其他一些功能吗?有没有其他方法可以实现这种行为,而不是将我的所有列表转换为(比如说)向量?
答案 0 :(得分:3)
这就是你所要求的:
(defn get-nth-in [init ks]
(reduce
(fn [a k]
(if (associative? a)
(get a k)
(nth a k)))
init
ks))
例如,
(-> '({:a "zero"} {:a "one"} {:a "two"})
(get-nth-in [1 :a]))
;"one"
和
(-> '({:a ("zero" 0)} {:a ("one" 1)} {:a ("two" 2)})
(get-nth-in [1 :a 0]))
;"one"
你已经扩展到'
的额外(quote ...)
:
(-> '({:a '("zero" 0)} {:a '("one" 1)} {:a '("two" 2)})
(get-nth-in [1 :a 0]))
;quote
我认为不是你的意图。
答案 1 :(得分:2)
A post just yesterday有关于惰性列表和延迟映射的问题(来自clojure / data.xml)。一个答案就是用普通的矢量&替换懒惰的比特。使用此功能的地图:
(defn unlazy
[coll]
(let [unlazy-item (fn [item]
(cond
(sequential? item) (vec item)
(map? item) (into {} item)
:else item))
result (postwalk unlazy-item coll)
]
result ))
由于结果数据结构仅使用矢量&地图,适用于get-in
的示例:
(let [l2 '({:a ("zero" 0)} {:a ("one" 1)} {:a ("two" 2)})
e2 (unlazy l2) ]
(is= l2 e2)
(is= "one" (get-in e2 [1 :a 0] l2))
)
您可以找到unlazy
函数in the Tupelo library.
答案 2 :(得分:-1)
get-in的第一个参数应该是地图。
你必须弄清楚你的序列的特征,使用最后,第一,过滤或一些例如首先获得元素
例如,您可以使用(:a (last data))