我不明白为什么而不是正常的列表我回忆(clojure.core / seq)。 我的代码
(defn del-list [arg-list lvl] (do
(cond
(= lvl 1) (remove seq? arg-list)
:else (map #(if (seq? %)
(del-list % (- lvl 1))
%
) arg-list)
)
))
(println (del-list `(1 2 3 `(1 2 `(1 2 3) 3) 1 2 3) 2))
;result=> (1 2 3 (clojure.core/seq) 1 2 3)
为什么会这样?我不知道如何有效搜索这个,谷歌的所有链接都指向我,有关seq
和seq?
的文档。
答案 0 :(得分:1)
像@ClojureMostly在评论中所说,不要使用bacticks,使用单引号。也不要嵌套它们,一个就足够了。
所以,像这样调用你的函数:
(println (del-list '(1 2 3 (1 2 (1 2 3) 3) 1 2 3) 2))
将解决您当前的问题。
进一步深入,单引号(仅称为引用)和反引号(称为语法引用)之间存在一些差异。
在引用某些内容时,您说您只需要数据结构,不应将其评估为代码。在clojure中,代码是数据,因此(+ 1 2)
是一个带有符号和两个数字的列表,当作为代码进行评估时,它会变为3.因此,(+ 1 2)
=> 3
和'(+ 1 2)
=> (+ 1 2)
。
语法引用类似,但它查找事物的命名空间,你可以在内部取消引用。这使它对编写宏很有用。
;; Looks up the namespaces of symbols to avoid the problem of variable capture
`(+ 1 2) ;=> (clojure.core/+ 1 2)
;; You can unquote parts of the expression.
;; ~ is unquote ~@ is unqoute splicing
;; That should give you the vocabulary to google this.
`(+ 1 2 3 ~(* 2 2)) ;=> (clojure.core/+ 1 2 3 4)
嵌套引号绝不是你想要的。 (除非你交替引用和取消引用,即便如此,它通常会令人困惑)
在clojure中,您通常将顺序事物表示为向量[1 2 3]
(O(n)随机访问,最后增长),除非您特别想要数据链表的某些属性。 (就像表示堆栈一样,列表可以有效地添加和删除第一个元素。)
(defn del-list [arg-list lvl]
;; You don't need the do, there's an implicit do in many special forms
;; like let, fn and defn
;; Also you only had one thing in your do, in that case it doesn't do anything
;; There's only one condition, so I'd use if instead of cond
(if (= lvl 1)
;; And, like someone mentioned in the comments,
;; what you probably want is sequential? instead of seq?
(remove sequential? arg-list)
(map #(if (sequential? %)
(del-list % (dec lvl)) ; dec stands for decrement
%)
arg-list)))
;; This works
(println (del-list '(1 2 3 (1 2 (1 2 3) 3) 1 2 3) 2))
;; But this is more idiomatic (modulo specific reasons to prefer lists)
(println (del-list [1 2 3 [1 2 [1 2 3] 3] 1 2 3] 2))
;; If you change map to mapv, and wrap remove with vec it will return vectors
(defn del-vec [arg-vec lvl]
(if (= lvl 1)
(vec (remove sequential? arg-vec))
(mapv #(if (sequential? %)
(del-vec % (dec lvl)) ; dec stands for decrement
%)
arg-vec)))
(println (del-vec [1 2 3 [1 2 [1 2 3] 3] 1 2 3] 2))
;; But most of the time you don't care about the specific type of sequential things
至于你的实际问题,为什么会出现clojure.core / seq,我不知道。这不是你如何使用引用,所以它从来没有出现过。