如何在Clojure中的深层嵌套数据结构(向量和列表)中找到索引?

Ert*_*tin 5 clojure

我正在尝试从嵌套数据结构中获取值的索引路由。

我已经写了一些代码,但是不能正常工作

(defn helper
  [val form c index]
  (loop [f form
         i index
         l 0]
    (if (seq f)
      (if (or (list? (first f)) (vector? (first f)))
        (helper val (first f) (conj c l) (inc i))
        (if (= val (first f))
          (conj c l)
          (recur (rest f) (inc i) (inc l))))
      nil)))

(defn find-indexes
  [val form c index]
  (when (seq form)
    (if-let [result (helper val form c index)]
      result
      (find-indexes val (rest form) c (inc index)))))

(defn find-index-route
  [val form]
  (find-indexes val form [] 0))
Run Code Online (Sandbox Code Playgroud)

当前行为:

(find-index-route :my-key '(1 2 ("a" :my-key))) ;=> [2 1] "Works"

(find-index-route :my-key '(1 2 ("a" ["b" 3 :my-key]))) ;=> [2 1 2] "Works"

(find-index-route :my-key '(1 2 ("a" ["b" 3 () :my-key]))) ;=> nil "Does NOT Work"

(find-index-route :my-key '(1 2 ("a" [] ["b" 3 :my-key]))) ;=> nil "Does NOT Work"

(find-index-route :my-key '(1 2 [] ("a" ["b" 3 :my-key]))) ;=> [0 1 2] "It has to be [3 1 2]"
Run Code Online (Sandbox Code Playgroud)

问题是,如果函数在找到值之前击中空列表或向量,则返回nil或0(仅是第一个级别)

我需要的行为:

                                          ;=> [indexes...]

(find-index-route :my-key '(1 2 :my-key)) ;=> [2]

(find-index-route :my-key '(1 2 "a" :my-key "b")) ;=> [3]

(find-index-route :my-key '(1 2 [:my-key] "c")) ;=> [2 0]

(find-index-route :my-key '(1 2 [3 [:my-key]])) ;=> [2 1 0]

(find-index-route :my-key '(1 2 [3 [[] :my-key]])) ;=> [2 1 1]

(find-index-route :my-key '(1 2 [3 [4 5 6 (:my-key)]])) ;=> [2 1 3 0]

(find-index-route :my-key '(1 2 [3 [[]]])) ;=> nil or []
Run Code Online (Sandbox Code Playgroud)