[英]Destructure a list two elements at a time (Clojure)
這個問題有很多種形式。 例如,給定輸入'(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))))))
理想情況下,列表將被懶散地消費和生成。 謝謝。
(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))
這是一種懶惰的方式:
user=> (mapcat reverse (partition 2 '(1 2 3 4 5 6)))
(2 1 4 3 6 5)
避免中間對象創建(要連接的矢量/ 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)))))
通常情況下,我會使用類似tom的答案,只使用mapcat
而不是flatten
:
(defn helper [xs]
(mapcat reverse (partition-all 2 xs)))
您需要使用partition-all
而不是partition
來避免從奇數長度的列表中刪除最終元素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.