我正在将一些LISP功能迁移到Clojure。我对StackOverflow消息有以下功能的问题:
(defn m
[list depth]
(cond
(= list nil) depth
(atom (first list)) (m (rest list) depth)
(> (m (first list) (+ depth 1)) (m (rest list) depth)) (m (first list) (+ depth 1))
:default (m (rest list) depth))
)
(defn n
[list depth maxdepth]
(cond
(= list nil) nil
(= depth maxdepth) list
(atom (first list)) (n (rest list) depth maxdepth)
(= 0 (n (first list) (+ depth 1) maxdepth)) (n (last list) depth maxdepth)
:default (n (first list) (+ depth 1) maxdepth))
)
(defn myfind[mylist]
(n mylist 0 (m mylist 0))
)
我基本上想要的是最嵌套列表的输出,如:
(myfind '(1 2 3 (4 5) 6 ((7 8) 9)))
=> (7 8)
目标是使用递归并最小化内置函数的使用来实现这一点。
这种情况有什么问题?
答案 0 :(得分:0)
(defn- deepest-with-depth [depth s]
(let [nested-colls (filter coll? s)]
(if (seq nested-colls)
(mapcat (partial deepest-with-depth (inc depth)) nested-colls)
[[depth s]])))
(defn deepest [s]
(->> (deepest-with-depth 0 s)
(apply max-key first)
second))
> (deepest '(1 2 3 (4 5) 6 ((7 8) 9)))
(7 8)
如果它们与您的要求发生冲突,请随意将某些函数调用(例如max-key
,partial
)替换为其实现。
答案 1 :(得分:0)
(defn- max-depth-entry [a-list]
(let [sub-lists (filter coll? a-list)
[depth list] (if (empty? sub-lists)
[0 a-list]
(apply max-key first (map max-depth-entry sub-lists)))]
[(inc depth) list]))
(max-depth-entry '(1 2 3 (4 5) 6 ((7 8) 9)))
;[3 (7 8)]
然后
(def max-depth-sublist (comp second max-depth-entry))
(max-depth-sublist '(1 2 3 (4 5) 6 ((7 8) 9)))
;(7 8)
我的想法是max-key
使用OlegTheCat's answer。我最初使用reduce
:
(defn- max-depth-entry [a-list]
(let [sub-lists (filter coll? a-list)
[a-list a-depth] (reduce
(fn ([] [a-list 0])
([[as an :as asn] [s n :as sn]] (if (> n an) sn asn)))
(map max-depth-entry sub-lists))]
[a-list (inc a-depth)]))
然后
(def max-depth-sublist (comp first max-depth-entry))
现在我已经准备好回到Sequs Horribilis on 4Clojure,直到现在一直困扰着我。
答案 2 :(得分:0)
这里还有一个变种,只有经典的旧学校解决方案,而且根本没有特定的clojure序列功能:
(defn deepest [items depth]
(if (sequential? items)
(let [[it1 d1 :as res1] (deepest (first items) (inc depth))
[it2 d2 :as res2] (deepest (next items) depth)]
(cond (>= depth (max d1 d2)) [items depth]
(>= d1 d2) res1
:else res2))
[items -1]))
它的嵌套列表递归的经典方法也值得注意:首先你重复car
,然后再cdr
,然后结合这些结果。
user> (deepest '(1 2 3 (4 5) 6 ((7 8) 9)) 0)
[(7 8) 2]
user> (deepest '(1 2 3 (4 5) 6) 0)
[(4 5) 1]
user> (deepest '(1 2 3 (x ((y (z)))) (4 5) 6) 0)
[(z) 4]
user> (deepest '(1 2 3 (x ((y (z)))) (4 5 ((((((:xxx)))))))) 0)
[(:xxx) 7]
user> (deepest '(1 2 3 ((((((((nil)))))))) (x ((y (z)))) (4 5) 6) 0)
[(nil) 8]
user> (deepest '(1 2 3) 0)
[(1 2 3) 0]