如何在clojure中的一个if块中写入多个语句?

时间:2014-10-22 05:46:13

标签: clojure clojurescript

我在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)

3 个答案:

答案 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)))