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

是否可以将clojure向量分解为最后两项和其他项?,clojure,destructuring,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))) 它试图找出是否有更方便的方法直接在函数参数中实现这一点 user=> (def v (vec (range 0

我知道我可以像这样“从前面”分解向量:

(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
我的建议是抛开方便,使用
peek
pop
来处理向量的结尾。当您的输入向量非常大时,您将看到巨大的性能提升


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

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

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

我以前没有使用过
rseq
,它非常适合这个问题。我对它进行了计时,从性能角度来看,它非常接近我的答案。