Есть ли более простой способ найти последний элемент массива в clojure, кроме этой функции?Последний элемент массива в Clojure
(fn [l] (if (empty? (rest l)) (first l) (recur (rest l))))
Есть ли более простой способ найти последний элемент массива в clojure, кроме этой функции?Последний элемент массива в Clojure
(fn [l] (if (empty? (rest l)) (first l) (recur (rest l))))
Для векторов, использование заглядывать для постоянного времени
user=> (peek [1 2 3 4 5])
5
Для Java массивов,
user=> (let [a (to-array [1 2 3 4 5])] (aget a (dec (alength a))))
5
Для общей коллекции, вы можете получить последний элемент в линейное время с last
. Он определяется аналогично тому, что вы сделали.
user=> (source last)
(def
^{:arglists '([coll])
:doc "Return the last item in coll, in linear time"
:added "1.0"
:static true}
last (fn ^:static last [s]
(if (next s)
(recur (next s))
(first s))))
Самый простой способ заключается в использовании (last l)
, который работает в линейном времени (http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/last)
Другая возможность заключается в том, чтобы поменять местами сбора и взять первый элемент: ((comp first reverse) l)
. Но это довольно медленно, так как обратная возвращает нелазную последовательность. Примечание: comp
возвращает состав своих аргументов (функций) (http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/comp)
Вы также можете преобразовать коллекцию в вектор сначала, а затем применить peek: ((comp peek vec) l)
. Это должно иметь лучшую производительность.
Другой: определите длину вашей коллекции и возьмите последний элемент (#(nth % (dec (count %))) l)
.
Эти функции работают для всех типов сбора (например, векторов, списков, ...). В Clojure нет массивов (за исключением того, что вы хотите использовать Java-массивы).
также большое спасибо! – Bfcm
'# (peek (vec%))' не будет показывать лучшую производительность в обычном списке. 'peek' будет показывать лучшую производительность по векторам, чем' last' (и примерно так же, как '# (nth% (dec (count%)))). '# (first (reverse%))' для всех коллекций столь же плох '# (peek (vec%))' для обычных списков, потому что оба подразумевают полный обход; '# (first (rseq%)' было бы лучше, если коллекция 'Reversible', но большинство коллекций' Reversible' являются векторами, для которых есть лучшие альтернативы. – omiel
Верно, однако, На мой взгляд, Bfcm искал простые и альтернативные методы и идеи для получения последнего элемента. Поскольку Bfcm, вероятно, говорил о векторах («массивы»), '((comp peek vec) l)' должен иметь лучшую производительность. – Pold