(for [[a b] (partition 2 '(1 2 3 4 5 6))
i [b a]]
i)
OR something resembling the haskell version:
(defn helper
([] (list))
([x] (list x))
([x y & r] (concat [y x] (apply helper r))))
(apply helper '(1 2 3 4 5 6))
سؤال
This problem takes many forms. For example, given the input '(1 2 3 4 5 6), we might want to swap the values between even and odd pairs. The output would be '(2 1 4 3 6 5).
In Haskell, this is rather easy:
helper [] = []
helper [x] = [x]
helper (x : y : ys) = y : x : helper ys
I wrote some Clojure code to accomplish the same task, but I feel that there is probably a cleaner way. Any suggestions on how to improve this?
(defn helper [[x y & ys]]
(cond
(nil? x) (list)
(nil? y) (list x)
:else (lazy-seq (cons y (cons x (helper ys))))))
Ideally the list would be consumed and produced lazily. Thanks.
المحلول
(for [[a b] (partition 2 '(1 2 3 4 5 6))
i [b a]]
i)
OR something resembling the haskell version:
(defn helper
([] (list))
([x] (list x))
([x y & r] (concat [y x] (apply helper r))))
(apply helper '(1 2 3 4 5 6))
نصائح أخرى
Avoiding intermediate object creation (vectors / seqs to be concatenated) and in direct correspondence to the Haskell original while handling nil
items in the input (which the approach from the question text doesn't):
(defn helper [[x & [y & zs :as ys] :as xs]]
(if xs
(lazy-seq
(if ys
(cons y (cons x (helper zs)))
(list x)))))
Normally I'd use something like tom's answer though, only with mapcat
rather than flatten
:
(defn helper [xs]
(mapcat reverse (partition-all 2 xs)))
You need to use partition-all
rather than partition
to avoid dropping the final element from lists of odd length.
This is one lazy way to do it:
user=> (mapcat reverse (partition 2 '(1 2 3 4 5 6)))
(2 1 4 3 6 5)