嵌套列表遍历

时间:2013-11-04 13:53:59

标签: clojure

我想编写一个函数,给定一个可能嵌套的列表会返回每个叶子的索引列表,这样我就可以用nth和那些索引减少列表并获取每个叶子。例:给定lst =((ab)c)它将返回((0 0)(0 1)(1))因为(减少第n个lst [0 0])= a(减少第n个lst [0 1])= b和(减少第n lst [1])= c。

编辑:这是我使用clojure.zip的解决方案。任何人都可以拿出更优雅的一个吗?

(defn tree-indexes [zipper matcher pos accumulator]
  (loop [loc zipper pos pos accumulator accumulator]
    (if (z/end? loc)
      accumulator
      (if (matcher (z/node loc))        
        (if (z/right loc)
          (recur (z/next loc) (update-in pos [(- (count pos) 1)] inc) (conj accumulator [(z/node loc) pos]))
          (if (z/end? (z/next loc))
            (recur (z/next loc) pos (conj accumulator [(z/node loc) pos]))
            (recur (z/next loc) (update-in (vec (butlast pos)) [(- (count (vec (butlast pos))) 1)] inc) (conj accumulator [(z/node loc) pos]))))
        (recur (z/next loc) (conj pos 0) accumulator)))))

1 个答案:

答案 0 :(得分:1)

我有一个(非尾部)递归解决方案,但可能存在某种迭代方法:

(defn list-indices
  ([l] (list-indices l []))
  ([l parent-indices]
   (->> l
        (map-indexed
          (fn [i element]
            (let [indices (conj parent-indices i)]
              (if (sequential? element)
                (list-indices element indices)
                [indices]))))
        (apply concat))))