是否可以将 clojure 向量解构为最后两项和其余项?

Is is possible to destructure a clojure vector into last two items and the rest?

我知道我可以像这样解构向量 "from the front":

(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))) 

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

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 处理向量的末尾。当您的输入向量非常大时,您会看到巨大的性能提升。

(另外,回答标题中的问题:没有。

您可以剥离最后两个元素并添加它们:

((fn [v] (let [[b a] (rseq v)] (+ a b))) [1 2 3 4])
; 7
  • rseq 快速提供向量的逆序列。
  • 我们只是解构它的前两个元素。
  • 其他的就不用说了,我们什么都不做。