Erica Maine
Erica Maine

Reputation: 147

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. 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])]. I know that the statement (v (rest vehicles) (rest locs)) is not executing because it's taking it in the else case i.e., when count(vehicles) not > 0. I want to know how can I make this statement be executed in the same if block, i.e., in (if (> (count vehicles) 0)

Upvotes: 2

Views: 1597

Answers (3)

Aleš Roubíček
Aleš Roubíček

Reputation: 5187

You can write multiple statements in if branches with a do form:

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

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

Upvotes: 1

hsestupin
hsestupin

Reputation: 1115

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. Here result is such a holder:

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

Upvotes: 2

Diego Basch
Diego Basch

Reputation: 13069

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

Upvotes: 3

Related Questions