Jako początkujący Clojure często mam trudności z wyrażeniem najprostszych rzeczy. Na przykład, dla zastąpienia ostatni element w wektorze, który byłbyJak zamienić ostatni element w wektor w Clojure
v[-1]=new_value
w Pythonie, I skończyć z następujących wariantów w Clojure:
(assoc v (dec (count v)) new_value)
który jest dość długi i bez wyrazu powiedzieć najmniej, lub jeszcze gorzej, ponieważ ma on czas działania w zakresie
To sprawia, że czuję się głupio, jak jaskiniowiec, który próbuje naprawić szwajcarski zegarek z pałką.
Jaki jest właściwy sposób Clojure do zastąpienia ostatniego elementu w wektorze?
Aby wspierać moje O(n)
-claim dla butlast
-version (Clojure 1.8):
(def v (vec (range 1e6)))
#'user/v
user=> (time (first (conj (vec (butlast v)) 55)))
"Elapsed time: 232.686159 msecs"
0
(def v (vec (range 1e7)))
#'user/v
user=> (time (first (conj (vec (butlast v)) 55)))
"Elapsed time: 2423.828127 msecs"
0
Więc w zasadzie do 10 czasu liczba elementów jest 10 razy wolniejsze.
Twoim pierwszym sposobem będzie to, jak to się robi. Oczywiście, możesz napisać funkcję "zastąpić ostatnią", aby ją wyczyścić. Myślę, że zbyt zwięzły sposób wyrażania Pythona zepsuł twoje oczekiwania. Nie sądzę, że indeksowanie z tyłu jest często potrzebne, aby wypowiadać własną składnię w Clojure. +1, ponieważ chciałbym zostać udowodniony źle. – Carcigenicate
Uwaga: rozwiązanie nr 3 nie jest O (n), jeśli 'v' jest już wektorem (zalecam, aby zawsze używać wektora Clojure na liście Clojure jako domyślnego wyboru, o ile pomiar nie wskaże inaczej). –
To jest dobrze rozgraniczone, konkretne pytanie i odpowiedź, ale myślę, że warto podkreślić, że wiele algorytmów wyrażonych za pomocą wyrażeń indeksu w Pythonie ma idiomatyczny ekwiwalent Clojure, który nie wymaga używania indeksów. – glts