Clojure ошибка простой функции сортировки - PullRequest
1 голос
/ 24 сентября 2011

Я новичок в clojure, я пытаюсь создать функции, которые будут сортировать коллекции и сохранять их в объекте.

Мой код:

(defn uniq [ilist]
  ([] [])
  (def sorted (sort ilist))) 

Я пытаюсь запустить его:

(uniq '(1,2,3,6,1,2,3))

но получаю ошибку:

#<CompilerException java.lang.IllegalArgumentException: Key must be integer (NO_SOURCE_FILE:0)>

Что не так?

Спасибо.

Ответы [ 3 ]

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

Как и в случае вашего другого вопроса , вы пытаетесь использовать сопоставление с образцом там, где оно просто не применяется. Ваша функция будет работать нормально 1 , если вы полностью удалите ([] []).

1 Вы также не должны использовать def здесь; как отметили другие респонденты, вы хотите использовать let для установления локальных привязок. Однако здесь вам вообще не нужны никакие привязки: просто верните результат вызова sort. Фактически, def заставит вас возвращать Var вместо фактического отсортированного списка.

2 голосов
/ 25 сентября 2011

Поскольку вообще нет необходимости использовать 'let' или 'def', я должен согласиться с Амаллой в ответе Барта J.Конечно, это оправдывает положительные отзывы, потому что это полезная информация, но это неправильный ответ.

На самом деле, определение функции является бесполезным, поскольку (сортировка ilist) поможет.Результатом функции является «объект», который вы хотите.То есть, если вы не хотите использовать результат сортировки , кратный раз, в различных местах в теле функции.В этом случае свяжите результат сортировки с локальной переменной функции.

Если вам нужна сортировка один раз , не связывайте ее вообще, а просто вкладывайте в другиефункции.Например, если вы хотите использовать его внутри уникальной функции (что, я думаю, именно то, что вы хотите сделать):

(defn uniq
  "Get only unique values from a list"
  [ilist]
    ; remove nils from list
    (filter #(not(nil? %))
      ; the list of intermediate results from (reduce comppair sortedlist)
      ; (includes nils)
      (reductions
        ; function to extract first and second from a list and compare
        (fn comppair
          [first second & rest]
          (if (not= first second) second))
        ; the original sort list function
        (sort ilist))))

(uniq '(1,2,3,6,1,2,3))
(1 2 3 6)

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

(distinct '(1,2,3,6,1,2,3))
(1 2 3 6)

(source distinct)
(defn distinct
  "Returns a lazy sequence of the elements of coll with duplicates removed"
  {:added "1.0"}
  [coll]
    (let [step (fn step [xs seen]
                   (lazy-seq
                    ((fn [[f :as xs] seen]
                      (when-let [s (seq xs)]
                        (if (contains? seen f) 
                          (recur (rest s) seen)
                          (cons f (step (rest s) (conj seen f))))))
                     xs seen)))]
      (step coll #{})))
1 голос
/ 24 сентября 2011

Чтобы сохранить отсортированную коллекцию в переменной , сделайте следующее:

(let [sorted (sort your-collection)])

Чтобы понять разницу между let и def, это должно помочь:

Вы можете использовать только лексические привязки, сделанные с помощью let, в области let (открывающая и закрывающая части).Пусть просто создает множество лексических привязок.Def и пусть сделать почти то же самое.Я использую def для создания глобальной привязки, а let - для привязки чего-то, что мне нужно, только в области действия let, поскольку она сохраняет чистоту.У них обоих есть свои цели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...