2013-11-04 142 views
1

我想写一个函数,给定一个可能的嵌套列表将返回一个每个叶子的索引列表,这样我可以减少列表中的第n个和那些索引并获得每个叶子。例如:给定lst =((ab)c)因为(减少第n个lst [0 0])= a(减少第n个lst [0 1])= b,它将返回((0 0)和(减少第n个[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))))) 
+0

如果你想要的是为了叶子,你可以只使用'扁平化'。 – Alex

回答

1

我有一个(非tail-)递归解决方案,但有可能是某种形式的迭代方法:

(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)))) 
+0

你的实现似乎并不正确(list-indices [[“a”“b”]“c”]) - > ([0] [1])。我正在尝试使用clojure.zip,这似乎是适合这份工作的。我会发布一个解决方案,如果它的工作。 – dmz73

+0

这是因为'seq?'和'list?'将向量返回'false'。你没有在你的问题中指定向量。 ;)我认为'顺序?'应该在这里工作。 – xsc

+0

谢谢!你的解决方案比我的要好得多。 – dmz73