Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何编写Clojure函数来返回相邻对的列表?_Clojure - Fatal编程技术网

如何编写Clojure函数来返回相邻对的列表?

如何编写Clojure函数来返回相邻对的列表?,clojure,Clojure,我试图编写一个函数邻接,它返回序列相邻对的向量。因此(邻接[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)))))) 我当前的实现适用于字符串序列,但对于整数或字符,REPL会输出以下错误: Ill

我试图编写一个函数
邻接
,它返回序列相邻对的向量。因此
(邻接[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))))))
我当前的实现适用于字符串序列,但对于整数或字符,REPL会输出以下错误:

IllegalArgumentException Don't know how to create ISeq from: java.lang.Long  clojure.lang.RT.seqFrom (RT.java:494)

这里的问题是在
(邻接[1 2 3])
的第一个求值循环中,
a
绑定到
1
,而
b
绑定到
2
。然后你问
b
是否为
空?
。但是
empty?
在序列上工作,而
b
不是序列,它是一个
长的
,即
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]]
但是,正如@amalloy所指出的,如果您的数据中存在合法的
nil
s,则这可能无法给出期望的结果:

user=> (adjacents [1 2 nil 4 5])
[[1 2]]
请参阅他的评论,了解使用列表的建议实现

请注意,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))

这是我的简短回答。一切都变成了一个向量,但它适用于所有序列

(defn adjacent-pairs [s] 
  {:pre [(sequential? s)]}
  (map vector (butlast s) (rest s)))
测试:

user=> (defn adjacent-pairs [s] (map vector (butlast s) (rest s))) 
#'user/adjacent-pairs
user=> (adjacent-pairs '(1 2 3 4 5 6))
([1 2] [2 3] [3 4] [4 5] [5 6])
user=> (adjacent-pairs [1 2 3 4 5 6])
([1 2] [2 3] [3 4] [4 5] [5 6])
user=> 

然而,这个答案可能比上面使用
分区的效率要低。

测试b的
nil?
是灾难性的,因为现在您无法计算
(邻接项'[xynil 5 6 7])
或类似的值。相反,您需要使用列表,例如通过
(循环[[x&xs]剩余](如果xs(让[y(第一个xs)]…))
。确实如此,这只是对OP代码的调整,使用最小的Levenshtein距离来解决问题。