简体   繁体   English

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

[英]How to write multiple statements in one if block in clojure?

I'm writing a function in clojure, that takes in 2 arguments (both are lists), and iterates over vehicles by recursion, until the vehicle list becomes empty. 我正在用clojure写一个函数,该函数接受2个参数(均为列表),并通过递归遍历车辆,直到车辆列表变为空。 The function is like: 函数就像:

(defn v [vehicles locs]
    (if (= (count vehicles) 0)
        nil
        (if (> (count vehicles) 0)
            (split-at 1 locs)
            (v (rest vehicles) (rest locs))
        ))
    )

So, if I give the input as (v '(v1 v2 v3) '([1 2] [2 3] [4 2] [5 3])) , then I want the output as [([1 2]) ([3 4]) ([5 6] [6 7])] . 因此,如果我将输入作为(v '(v1 v2 v3) '([1 2] [2 3] [4 2] [5 3])) ,则我希望输出为[([1 2]) ([3 4]) ([5 6] [6 7])] I know that the statement (v (rest vehicles) (rest locs)) is not executing because it's taking it in the else case ie, when count(vehicles) not > 0. I want to know how can I make this statement be executed in the same if block, ie, in (if (> (count vehicles) 0) 我知道该语句(v (rest vehicles) (rest locs))没有执行,因为在其他情况下(例如,count(车辆)不大于0)正在接受该语句。我想知道如何执行该语句在相同的if块中,即在(if (> (count vehicles) 0)

It sounds like you're trying to do something like this: 听起来您正在尝试执行以下操作:

(defn v [vehicles locs]
  (if (seq (rest vehicles))
    (concat  [[(first locs)]] (v (rest vehicles) (rest locs)))
    [locs]))

When you are using recursion and need to return some result of execution there is good approach to accumulate all of your recursion step's results in one holder variable. 当您使用递归并需要返回一些执行结果时,有一种很好的方法将所有递归步骤的结果累加到一个holder变量中。 Here result is such a 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))))))

It works like this: 它是这样的:

(v '(v1 v2 v3) '([1 2] [2 3] [4 2] [5 3]))
=> [[1 2] [2 3] ([4 2] [5 3])]

If you really need to wrap location one-element vectors (but actually it seems like a strange requirement) then try the following: 如果您确实需要包装位置一元向量(但实际上这似乎是一个奇怪的要求),请尝试以下操作:

(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))))))

You can write multiple statements in if branches with a do form: 您可以使用do形式在if分支中编写多个语句:

(if (= 1 (count vs))
  (do
    (conj result ls)
    (recur (conj result (first ls)) (rest vs) (rest ls)))
  :else)

If you don't need else branch it's convenient to use when macro: 如果不需要else分支,则使用when宏非常方便:

(when (= 1 (count vs))
  (conj result ls)
  (recur (conj result (first ls)) (rest vs) (rest ls)))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM