Clojure简单排序函数错误

时间:2011-09-24 16:59:31

标签: function sorting clojure

我是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 个答案:

答案 0 :(得分:5)

与您的other question一样,您尝试使用不适用的模式匹配。如果您完全删除了([] []),那么您的函数将正常工作 1

1 你也不应该在这里使用def;正如其他受访者所指出的那样,您希望使用let来建立本地绑定。但是,在这里您根本不需要任何绑定:只返回sort调用的结果。事实上,def将导致您返回Var而不是实际的排序列表。

答案 1 :(得分:2)

由于根本不需要使用'let'或'def',我必须同意关于Bart J答案的合金化。当然它保证赞成票,因为它是有用的信息,但它不是正确的答案。

实际上,定义函数是没用的,因为(sort ilist)可以解决问题。函数的结果是你想要的'对象'。也就是说,除非您想在函数体中的不同位置使用排序多次次的结果。在这种情况下,将sort的结果绑定到函数局部变量。

如果您只需要一次,那么根本不需要对其进行绑定,只需将其嵌套在其他函数中即可。例如,如果你想在一个独特的函数中使用它(我想这就是你想要做的):

(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 #{})))

答案 2 :(得分:1)

要将已排序的集合存储到变量,请执行以下操作:

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

要了解let和def之间的区别,this should help:

你只能在let(开始和结束的parens)范围内使用let生成的词法绑定。让我们创建一组词法绑定。 def,让我们做同样的事情。我使用def进行全局绑定,并允许在let的范围内绑定我想要的东西,因为它可以保持干净。他们都有自己的用途。