我是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)>
出了什么问题?
谢谢。
答案 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的范围内绑定我想要的东西,因为它可以保持干净。他们都有自己的用途。