在Clojure中递归反转序列

noa*_*hlz 8 recursion clojure

我想在不使用reverse函数的情况下反转Clojure中的序列,并以递归方式执行此操作.

这是我想出的:

(defn reverse-recursively [coll]
  (loop [r (rest coll)
         acc (conj () (first coll))]
    (if (= (count r) 0)
      acc
      (recur (rest r) (conj acc (first r))))))
Run Code Online (Sandbox Code Playgroud)

样本输出:

user> (reverse-recursively '(1 2 3 4 5 6))
(6 5 4 3 2 1)
user> (reverse-recursively [1 2 3 4 5 6])
(6 5 4 3 2 1)
user> (reverse-recursively {:a 1 :b 2 :c 3})
([:c 3] [:b 2] [:a 1])
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 有没有更简洁的方法来做到这一点,即没有循环/重复?
  2. 有没有办法在循环中不使用"累加器"参数的情况下执行此操作?

参考文献:

什么是在Java中递归反转字符串的最佳方法?

http://groups.google.com/group/clojure/browse_thread/thread/4e7a4bfb0d71a508?pli=1

Ale*_*art 24

  • 你不需要数数.当剩下的序列为空时停止.
  • 你不应该预先填充acc,因为原始输入可能是空的(并且它是更多的代码).
  • 解构很酷.
(defn reverse-recursively [coll]
  (loop [[r & more :as all] (seq coll)
         acc '()]
    (if all
      (recur more (cons r acc))
      acc)))

至于loop/ recuracc,你需要一些传递工作逆转列表的方法.它要么是loop,要么为函数添加另一个参数(loop无论如何,这实际上是在做什么).

或者使用更高阶函数:

user=> (reduce conj '() [1 2 3 4])
(4 3 2 1)

  • 关于"使用更高阶函数"检查`(源反向)` (7认同)

pan*_*rey 6

为详尽起见,还有一种方法使用into. 由于进入内部使用,conj它可以按如下方式使用:

(defn reverse-list 
  "Reverse the element of alist."
  [lst]
  (into '() lst))
Run Code Online (Sandbox Code Playgroud)