我正在尝试编写一个函数adjacents,该函数返回序列相邻对的向量。所以(adjacents [1 2 3])会回来[[1 2] [2 3]]。
(defn adjacents [s]
(loop [[a b :as remaining] s
acc []]
(if (empty? b)
acc
(recur (rest remaining) (conj acc (vector a b))))))
Run Code Online (Sandbox Code Playgroud)
我当前的实现适用于字符串序列,但对于整数或字符,REPL 会输出此错误:
IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seqFrom (RT.java:494)
Run Code Online (Sandbox Code Playgroud)
这里的问题是在第一次评估循环(adjacents [1 2 3]),a必然要1和b到2。然后你问是否b是empty?。但empty?适用于序列并且b不是序列,它是Long,即2。您可以在此案例中使用的谓词是nil?:
user=> (defn adjacents [s]
#_=> (loop [[a b :as remaining] s acc []]
#_=> (if (nil? b)
#_=> acc
#_=> (recur (rest remaining) (conj acc (vector a b))))))
#'user/adjacents
user=> (adjacents [1 2 3 4 5])
[[1 2] [2 3] [3 4] [4 5]]
Run Code Online (Sandbox Code Playgroud)
但是,正如@amalloy 指出的那样,如果您nil的数据中有合法的s ,这可能无法给出预期的结果:
user=> (adjacents [1 2 nil 4 5])
[[1 2]]
Run Code Online (Sandbox Code Playgroud)
有关使用列表的建议实现,请参阅他的评论。
请注意,partition可以使用Clojure来完成这项工作,而无需定义您自己的:
user=> (partition 2 1 [1 2 3 4 5])
((1 2) (2 3) (3 4) (4 5))
user=> (partition 2 1 [1 2 nil 4 5])
((1 2) (2 nil) (nil 4) (4 5))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
661 次 |
| 最近记录: |