是否有可能将一个clojure矢量解构为最后两个项目,其余的?

时间:2015-12-08 23:15:25

标签: clojure destructuring

我知道我可以像这样“从前面”构建一个矢量:

(fn [[a b & rest]] (+ a b))

是否有(短)方式访问最后两个元素

(fn [[rest & a b]] (+ a b)) ;;Not legal

我目前的替代方案是

(fn [my-vector] (let [[a b] (take-last 2 my-vector)] (+ a b))) 

它试图找出是否有办法直接在函数参数中以更方便的方式做到这一点。

2 个答案:

答案 0 :(得分:14)

user=> (def v (vec (range 0 10000000)))
#'user/v
user=> (time ((fn [my-vector] (let [[a b] (take-last 2 my-vector)] (+ a b))) v))
"Elapsed time: 482.965121 msecs"
19999997
user=> (time ((fn [my-vector] (let [a (peek my-vector) b (peek (pop my-vector))] (+ a b))) v))
"Elapsed time: 0.175539 msecs"
19999997

我的建议是为方便风,并使用peekpop来处理向量的结尾。当您的输入向量非常大时,您将看到巨大的性能提升。

(另外,要回答标题中的问题:否。

答案 1 :(得分:13)

你可以剥掉最后两个元素,然后添加它们:

((fn [v] (let [[b a] (rseq v)] (+ a b))) [1 2 3 4])
; 7
  • rseq可以快速为矢量提供反向序列。
  • 我们只是解构其前两个元素。
  • 我们不需要提及其余部分,我们不做任何事情。