由於迄今爲止答案都沒有使用遞歸,你在問題中提到了,我會用遞歸解決方案作爲參考。
(def my-tree
'(3 (apple) -2 (50 orange) 9 banana))
(defn tree-nums-helper
[acc tree]
(cond
;; If tree is a collection, reduce tree-nums-helper over it using the
;; current acc as the initial value.
(coll? tree) (reduce tree-nums-helper acc tree)
;; So, tree is not a collection, it's a leaf.
;; If it's a number, add it to the accumulator.
(number? tree) (conj acc tree)
;; Else, just return the accumulator untouched.
:else acc))
(defn tree-nums
"Takes a tree and returns a vector of the numbers it contains
in depth first order."
[tree]
;; Just calls the helper with an empty accumulator.
(tree-nums-helper [] tree))
(tree-nums my-tree) ;=> [3 -2 50 9]
如果你想重新使用遞歸遍歷樹的邏輯來找到其他的事情不是數字,你可以寫一個函數,一個謂詞(即返回布爾函數),並返回一個樹行者。
;; dfs = depth first search
(defn dfs-factory [pred]
;; You can name anonymous functions so that you can recursively
;; refer to them from within themselves
(fn dfs
([tree]
(dfs [] tree))
;; Instead of having a helper fn, here we have an extra arity.
([acc tree]
(cond
(coll? tree) (reduce dfs acc tree)
(pred tree) (conj acc tree)
:else acc))))
(def tree-nums
(dfs-factory number?))
(tree-nums my-tree) ;=> [3 -2 50 9]
(def tree-syms
(dfs-factory symbol?))
(tree-syms my-tree) ;=> [apple orange banana]
你知道遞歸嗎? – Jeremy