我在clojure中编写一个函数,它接受2个参数(都是列表),并通过递归迭代车辆,直到车辆列表变空。功能如下:
(defn v [vehicles locs]
(if (= (count vehicles) 0)
nil
(if (> (count vehicles) 0)
(split-at 1 locs)
(v (rest vehicles) (rest locs))
))
)
因此,如果我将输入设为(v '(v1 v2 v3) '([1 2] [2 3] [4 2] [5 3]))
,那么我希望输出为[([1 2]) ([3 4]) ([5 6] [6 7])]
。我知道声明(v (rest vehicles) (rest locs))
没有执行,因为它在其他情况下接受它,即当计数(车辆)不是> 0.我想知道如何在同一个if块中执行此语句,即在(if (> (count vehicles) 0)
答案 0 :(得分:3)
听起来你正试图做这样的事情:
(defn v [vehicles locs]
(if (seq (rest vehicles))
(concat [[(first locs)]] (v (rest vehicles) (rest locs)))
[locs]))
答案 1 :(得分:2)
当你使用递归并且需要返回一些执行结果时,有一种很好的方法可以将所有递归步骤的结果累积到一个holder变量中。这里result
是这样的持有人:
(defn v [vehicles locs]
(if (empty? vehicles)
nil
(loop [result [] vs vehicles ls locs]
(if (= 1 (count vs))
(conj result ls)
(recur (conj result (first ls)) (rest vs) (rest ls))))))
它的工作原理如下:
(v '(v1 v2 v3) '([1 2] [2 3] [4 2] [5 3]))
=> [[1 2] [2 3] ([4 2] [5 3])]
如果你真的需要包装位置单元素向量(但实际上它似乎是一个奇怪的要求),那么尝试以下方法:
(defn v [vehicles locs]
(if (empty? vehicles)
nil
(loop [result [] vs vehicles ls locs]
(if (= 1 (count vs))
(conj result ls)
(recur (conj result (list (first ls))) (rest vs) (rest ls))))))
答案 2 :(得分:1)
您可以使用if
表单在do
分支中编写多个语句:
(if (= 1 (count vs))
(do
(conj result ls)
(recur (conj result (first ls)) (rest vs) (rest ls)))
:else)
如果您不需要else
分支,则可以方便地使用when
宏:
(when (= 1 (count vs))
(conj result ls)
(recur (conj result (first ls)) (rest vs) (rest ls)))