列表的加入

时间:2017-04-04 17:11:07

标签: clojure

显然get-in不适用于'()列表,因为它们不是关联数据结构。这对于API以及从大型列表的性能角度来说是有意义的。从我作为用户的角度来看,仍然可以使用此功能来探索repl中的一些小测试数据。例如,我希望能够:

(-> '({:a ("zero" 0)} {:a ("one" 1)} {:a ("two" 2)})
     (get-in [1 :a 0]))

=> "one"

还有其他一些功能吗?有没有其他方法可以实现这种行为,而不是将我的所有列表转换为(比如说)向量?

3 个答案:

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