我怎么能转换这个:
[a b c d e]
或这个:
(e d c b a) ;(rseq [a b c d e])
对此:
[a[b[c[d[e]]]]]
我一直在绞尽脑汁,我觉得有一个简单的解决方案!:-\
最终我想这样做:
[a b c d e]
[a b c x y]
[a b c d j k]
像这样:
{a {b {c {d {e}
{j {k}}
{x {y}}}}
我认为 conj 会有所帮助
我怎么能转换这个:
[a b c d e]
或这个:
(e d c b a) ;(rseq [a b c d e])
对此:
[a[b[c[d[e]]]]]
我一直在绞尽脑汁,我觉得有一个简单的解决方案!:-\
最终我想这样做:
[a b c d e]
[a b c x y]
[a b c d j k]
像这样:
{a {b {c {d {e}
{j {k}}
{x {y}}}}
我认为 conj 会有所帮助
(更新:在原始问题的答案下方的编辑中添加了新问题的答案。)
实际上,我最近在#clojure 中回答了这个问题。
这里有两种方法:f几乎是将规范直接转换为代码,但是它会创建一个 seq -- (next xs)-- 在每一步都会立即注入一个新的向量;g是一个更好的版本,它只分配实际出现在输出中的对象,加上一个向量和 seq 链接来遍历它:
;; [1 2 3] -> [1 [2 [3]]]
;; naive, quadratic:
(defn f [xs]
(if (next xs)
[(first xs) (vec (f (next xs)))]
(vec xs)))
;; only allocates output + 1 vector + a linear number of seq links,
;; linear overall:
(defn g [v]
(reduce (fn [acc x]
[x acc])
[(peek v)]
(rseq (pop v))))
注意。我忽略了向量运算产生的通常对数因子(所以这是软 O复杂性)。
至于生成嵌套地图,上述内容并不是特别有用。这是一种方法:
(defn h
([v]
(h nil v))
([m v]
(assoc-in m v nil)))
(h [1 2 3 4])
;= {1 {2 {3 {4 nil}}}}
(def data
'[[a b c d e]
[a b c x y]
[a b c d j k]])
(reduce h {} data)
;= {a {b {c {x {y nil}, d {j {k nil}, e nil}}}}}
我nil用作“终结者”,因为{y}(目前在答案文本中找到)不是格式正确的文字。true如果您打算将这些映射调用为检查键是否存在的函数,这可能是一个更方便的选择。
这里更简单的解决方案(使用解构和非尾递归):
(defn wrap
([[a & as]]
(if-let [[b & cs] as]
[a (wrap as)]
[a])))