2014-02-11 4 views

ответ

10

Для векторов, использование заглядывать для постоянного времени

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)))) 
1

Самый простой способ заключается в использовании (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-массивы).

+0

также большое спасибо! – Bfcm

+0

'# (peek (vec%))' не будет показывать лучшую производительность в обычном списке. 'peek' будет показывать лучшую производительность по векторам, чем' last' (и примерно так же, как '# (nth% (dec (count%)))). '# (first (reverse%))' для всех коллекций столь же плох '# (peek (vec%))' для обычных списков, потому что оба подразумевают полный обход; '# (first (rseq%)' было бы лучше, если коллекция 'Reversible', но большинство коллекций' Reversible' являются векторами, для которых есть лучшие альтернативы. – omiel

+0

Верно, однако, На мой взгляд, Bfcm искал простые и альтернативные методы и идеи для получения последнего элемента. Поскольку Bfcm, вероятно, говорил о векторах («массивы»), '((comp peek vec) l)' должен иметь лучшую производительность. – Pold

Смежные вопросы