获取Clojure中嵌套最多的列表
我正在将一些LISP函数迁移到Clojure。我对以下功能的StackOverflow消息有问题:获取Clojure中嵌套最多的列表,clojure,Clojure,我正在将一些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) (+ d
(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)
我们的目标是使用递归并尽量减少使用内置函数来实现这一点
这种情况有什么不对
(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
)
(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)]
如果某些函数调用与您的要求相冲突,请随意使用它们的实现来替代它们(例如,max key
,partial
)
(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)]
然后
我的想法是使用
max key
。我最初是用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)]))
然后
现在我准备回到过去,这一直困扰着我 然后
我的想法是使用
max key
。我最初是用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)]))
然后
现在我准备回到过去,这一直困扰着我 这里还有一个变体,只有经典的老式解决方案,根本没有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]
这里还有一个变体,只有经典的老式解决方案,并且根本没有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]
clojure.core/atom([x][x&options])创建并返回一个初始值为x的原子和零个或多个选项
…我删除了atom,但仍然得到堆栈溢出,输出为:stackOverflowerr ppj.core/m(form-init7572722406191330769.clj:4)ppj.core/m(form-init7572722406191330769.clj:6)。。。所有关于如何解决这个问题的想法都非常受欢迎:)你能提供一个为什么不使用库函数来解决这个问题的原因吗?这是我必须遵循的要求…clojure.core/atom([x][x&options])创建并返回一个初始值为x、选项为零或更多的原子
…我已删除了原子,但仍然得到堆栈溢出,输出为:stackoverflowerr ppj.core/m(form-init7572722406191330769.clj:4)ppj.core/m(form-init7572722406191330769.clj:6)。。。所有关于如何解决这个问题的想法都非常受欢迎:)你能提供一个为什么不使用库函数来解决这个问题的原因吗?这是我必须遵循的要求…谢谢OlegTheCat,就是这样!谢谢OlegTheCat,就是这个!