моя собственная функция вставки в качестве упражнения - PullRequest
3 голосов
/ 27 сентября 2011

Я решаю упражнение 4Clojure, в этом упражнении вас попросят создать собственную функцию вставки.Мой ответ следующий:

(fn my-interpose 
  ([separator input] (my-interpose separator input nil))
  ([separator input result] 
    (if 
      (empty? input) 
      (reverse (rest result))
      (my-interpose separator (rest input) (cons separator (cons (first input) result))))))

Я делаю эти упражнения, чтобы выучить язык, когда читаю книгу Clojure.Я хотел бы узнать мнение о моем кодексе людей с опытом работы на языке.Могу ли я избежать обратного звонка?Есть ли какие-то соглашения, которые я с трудом нарушаю с помощью такого кода?

Ответы [ 5 ]

5 голосов
/ 27 сентября 2011

То, что у вас есть, является хорошей правильной отправной точкой :).Отличная работа.

Начиная с того, что у вас есть, вы можете захотеть:

  • Заменить рекурсивный вызов на вызов recur, поскольку, как написано, он попадет в стекПереполнение

    (defn foo [stuff]
      (dostuff ... )
      (foo (rest stuff)))
    

    становится:

    (defn foo [stuff]
      (dostuff ...)
      (recur (rest stuff)))
    

    , чтобы избежать перегрузки стека.тогда это часто становится:

    (map dostuff stuff)

  • Заменить процесс рекуперации полностью функцией for

    (for [a one-list b another-list]
      (dont-give-away-the-answer))
    
3 голосов
/ 27 сентября 2011

Да, вы можете избежать обратного вызова,

(defn my-interpose [sep coll]
  (when (seq coll)
    (lazy-cat [(first coll) sep]
              (my-interpose sep (rest coll)))))

как и полагает Артур, вы можете использовать recur, чтобы не выбрасывать стек, но в 99% случаев он вам не нужен.

EDIT:

Это немного чище,

(defn my-interpose [sep coll]
  (if-let [[first & rest] coll]
    (lazy-cat [first sep] (my-interpose sep rest))))
2 голосов
/ 28 сентября 2011

Получил различные ответы, используя mapcat и for, но в конце концов я нашел это:

#(rest (interleave (repeat %1) %2))

Где первый аргумент - это разделитель, а второй - это коллекция. Просто опубликовать этот ответ для чистого любопытства других новичков Clojure, таких как я.

1 голос
/ 02 января 2014

Вы можете использовать map

(defn my-interpose [sep coll]
  (rest (apply concat (map #(vector sep %) coll))))

или напрямую уменьшить и вычислить ответ по ходу

(defn my-interpose [sep coll]
  (rest (reduce #(conj %1 sep %2) [] coll)))

Идея заключается в том, чтобы вычислить последовательность, подобную (sep x0 sep x1 sep x2 ... sep xn), а затем пропустить первый элемент, чтобы получить (x0 sep x1 sep x2 ... xn).

1 голос
/ 28 сентября 2011

Вот мое решение: я пытаюсь опираться на функции lisp более низкого уровня или схемы.

(defn my-interpose[sep coll]                                                                                                                                                                                                                
  (letfn [(f [c]                                                                                                                                                                                                                            
            (when-not (empty? c)                                                                                                                                                                                                            
              (cons sep (cons (first c)                                                                                                                                                                                                     
                              (f (next c))))))]                                                                                                                                                                                             
    (next (f coll))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...