2015-12-08 22 views
6

wiem, że mogę destructure wektor „od przodu” tak:Czy możliwe jest zniszczenie wektora wróżki na dwa ostatnie elementy, a reszta?

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

Czy istnieje jakiś (krótki) sposób uzyskiwania dostępu do dwa ostatnie elementy zamiast?

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

Mój obecny alternatywą jest

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

i próbuje dowiedzieć się, czy istnieje sposób, aby to zrobić w bardziej dogodny sposób bezpośrednio w argumentach funkcji.

Odpowiedz

9

można odkleić dwa ostatnie elementy i dodać je w ten sposób:

((fn [v] (let [[b a] (rseq v)] (+ a b))) [1 2 3 4]) 
; 7 
  • rseq dostarcza odwrotnie sekwencja dla wektora w krótkim czasie.
  • Po prostu niszczymy pierwsze dwa elementy.
  • Nie musimy wspominać o reszcie tego, z czym nic nie robimy.
+1

Nie użyłem wcześniej 'rseq' i idealnie pasuje do tego pytania. Przerwałem to na czas i jest to bardzo zbliżone do moich wyników. – WolfeFan

11
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 

Moja rada byłoby wyrzucić wygodę wiatrem i używać peek i pop pracę z końcem wektora. Kiedy twój wektor wejściowy jest bardzo duży, zobaczysz niesamowitą wydajność.

(również odpowiedzieć na pytanie w tytule. bez)

+0

Niiiccceee wydajne rozwiązanie !!! –