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

ece*_*ulm 8 clojure destructuring

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

(fn [[a b & rest]] (+ a b))
Run Code Online (Sandbox Code Playgroud)

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

(fn [[rest & a b]] (+ a b)) ;;Not legal
Run Code Online (Sandbox Code Playgroud)

我目前的替代方案是

(fn [my-vector] (let [[a b] (take-last 2 my-vector)] (+ a b))) 
Run Code Online (Sandbox Code Playgroud)

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

Wol*_*Fan 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
Run Code Online (Sandbox Code Playgroud)

我的建议是抛出的方便了风和使用peek,并pop与载体的把工作进行到底.当您的输入向量非常大时,您将看到巨大的性能提升.

(另外,回答标题中的问题:不.)


Thu*_*ail 13

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

((fn [v] (let [[b a] (rseq v)] (+ a b))) [1 2 3 4])
; 7
Run Code Online (Sandbox Code Playgroud)
  • rseq 在快速时间内为矢量提供反向序列.
  • 我们只是解构它的前两个元素.
  • 我们不需要提及其余部分,我们不做任何事情.

  • 我之前没有使用过`rseq`,它非常适合这个问题.我计时了,而且我的答案非常接近表现. (2认同)