这个问题有很多种形式。例如,给定输入'(1 2 3 4 5 6),我们可能想要在偶数对和奇数对之间交换值。输出为'(2 1 4 3 6 5)。
在Haskell中,这很容易:
helper [] = []
helper [x] = [x]
helper (x : y : ys) = y : x : helper ys
我写了一些Clojure代码来完成同样的任务,但我觉得可能有一种更清洁的方式。关于如何改进这个的任何建议?
(defn helper [[x y & ys]]
(cond
(nil? x) (list)
(nil? y) (list x)
:else (lazy-seq (cons y (cons x (helper ys))))))
理想情况下,列表会被懒散地消耗和生成。感谢。
答案 0 :(得分:4)
(for [[a b] (partition 2 '(1 2 3 4 5 6))
i [b a]]
i)
或类似于haskell版本的东西:
(defn helper
([] (list))
([x] (list x))
([x y & r] (concat [y x] (apply helper r))))
(apply helper '(1 2 3 4 5 6))
答案 1 :(得分:3)
这是一种懒惰的方式:
user=> (mapcat reverse (partition 2 '(1 2 3 4 5 6)))
(2 1 4 3 6 5)
答案 2 :(得分:3)
避免中间对象创建(要连接的矢量/ seq)并与Haskell原始文件直接对应,同时处理输入中的nil
项(问题文本中的方法不是):
(defn helper [[x & [y & zs :as ys] :as xs]]
(if xs
(lazy-seq
(if ys
(cons y (cons x (helper zs)))
(list x)))))
通常情况下,我会使用汤姆的答案,只能使用mapcat
而不是flatten
:
(defn helper [xs]
(mapcat reverse (partition-all 2 xs)))
您需要使用partition-all
而不是partition
来避免从奇数长度的列表中删除最终元素。