2011-09-24 101 views
1

我是新的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)> 

有什么不对?

谢谢。

+0

你想要什么输出?集合的独特元素? –

+0

不,现在,只有排序列表 – 0xAX

+1

要存储和返回变量,可以使用let。你应该这样做:(let [sorted(sort list-elements)] sorted –

回答

1

到分类收集存储到变量做到这一点:

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

要了解一个让和高清之间的区别,this should help:

您只能使用与取得的词法绑定在let的范围内(开始和结束的parens)。只需创建一组词汇绑定。 def并让它做几乎相同的事情。我使用def来进行全局绑定,并允许绑定我只希望在let的范围内的东西,因为它使事情保持干净。他们都有他们的用途。

+1

为什么每个人都忽略停止显示的语法错误,并且关注一个重要但微妙的细节?如果他的代码在它到达那里之前抛出异常,他就不会学习使用“local”def的恶意。 – amalloy

+0

注意点。我无法删除我的答案,因为它已被接受。所以把它变成“社区wiki”吧。 –

5

与您的other question一样,您尝试在不适用的情况下使用模式匹配。如果您完全删除([] []),您的功能将正常工作。

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

2

因为完全没有必要使用'let'或'def',所以我必须同意amalloy关于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 #{}))) 
+0

+1给你和amalloy,但这基本上是一个巨大的SO问题:在这里有无数的“答案”,这些答案根本不是答案,而且还不仅被接受,而且被高估。有80 + upvotes答案是完全虚假的,并且出现“第一”,即使有进一步下来真正正确的答案,数百upvotes。整个“接受答案”和“接受答案的业力 - 妓女”(我不是在谈论“Bart J”顺便说一句,我正在谈论这个非常概念)完全被打破了。应该有上升和下降,但没有“接受答案”的概念。 – SyntaxT3rr0r