clojure найти последний элемент без использования последней функции - PullRequest
23 голосов
/ 25 ноября 2011

Я изучаю clojure и использую 4clojure.com , чтобы стать лучше. Я только что закончил # 19 , но, похоже, возможно, я не сделал этого совсем так, как ожидал автор - как будто я, возможно, как-то упустил суть.

4 clojure problem 19

Учитывая ограничение, что вы не можете использовать последнюю функцию , кажется ли это разумным решением?

#(.get %(- (count %) 1))

Ответы [ 8 ]

41 голосов
/ 12 апреля 2012

Если вы собираетесь использовать:

#(first (reverse %))

Вы также можете составить функцию с помощью "comp":

(comp first reverse)

Это, вероятно, немного более идиоматично и легче для чтения. Здесь применяется то же самое предостережение о том, что «обратный» - не ленивый.

26 голосов
/ 25 ноября 2011

Это правильное решение. Я бы назвал #(nth % (dec (count %))) более идиоматичным, но они функционально эквивалентны.

21 голосов
/ 25 ноября 2011

А как же

reduce (fn [a b] b)

В бланке

18 голосов
/ 25 ноября 2011

Вот чисто рекурсивный подход, который не основан на подсчете:

(defn end [[n & more]]
  (if more
    (recur more)
    n))
8 голосов
/ 25 ноября 2011

Да, это разумное решение.Несколько вещей:

  1. Более идиоматично использовать функцию dec вместо вычитания на единицу.

    #(.get % (dec (count %)))

  2. Следуйте за другими людьми на 4clojure.Таким образом, вы сможете увидеть их решение проблемы после того, как решите ее.Я сам работаю с 4clojure и считаю очень полезным изучить язык, особенно некоторые идиомы.

  3. Первое решение, о котором я подумал, это просто перевернуть список и взятьпервый элемент.

    #(first (reverse %))

2 голосов
/ 17 ноября 2014

Я думаю, вы можете стать еще проще с чем-то вроде (comp peek vec). Я думаю, что проблема в том, что last работает с последовательностями и работает в линейном времени, как сказано в документации:

clojure.core / last ([coll]) Возвращает последний элемент в coll, в линейной время

peek, с другой стороны, быстрее, чем last согласно документам:

clojure.core / peek ([coll]) Для списка или очереди, такой же, как первая, для вектор, такой же, как, но гораздо эффективнее, чем в прошлом. Если коллекция пуста, возвращает ноль.

1 голос
/ 06 января 2016

Я не думаю, что мое решение лучше, чем кто-либо другой, но я думаю, что это другой способ решения той же проблемы:

(fn 
  [x] 
  (nth x (- (count x) 1)))

Используется fn.

0 голосов
/ 06 февраля 2016
(fn getLast [l] (if (= (count l) 1) (first l) (getLast (rest l))) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...