2

我有一个嵌套地图的 edn。我为这个 Clojure 找到了一个很好的例子:一个在嵌套的 hashmap 中搜索 val 并返回包含 val 的键序列的函数

(def coll
  {:a "aa"
   :b {:d "dd"
       :e {:f {:h "hh"
               :i "ii"}
           :g "hh"}}
   :c "cc"})

有了这个答案

(defn find-in [coll x]
    (some
(fn [[k v]]
  (cond (= v x) [k]
        (map? v) (if-let [r (find-in v x)]
                   (into [k] r))))
coll))

我的问题是,因为some我无法为每个结果找到路径,只有第一个逻辑真理。我试过map了,keep但他们打破了递归。我怎样才能让这段代码返回所有结果的路径,而不仅仅是第一个?任何帮助表示赞赏。

4

2 回答 2

2

您可以使用辅助函数将嵌套地图转换为具有完全限定键的平面地图。然后 find-in 可以只过滤值并返回匹配的键。

(defn flatten-map [path m]
  (if (map? m)
    (mapcat (fn [[k v]] (flatten-map (conj path k) v)) m)
    [[path m]]))

(defn find-in [coll x]
  (->> (flatten-map [] coll)
       (filter (fn [[_ v]] (= v x)))
       (map first)))

使用您的样品:

(find-in coll "hh")
=>
([:b :e :f :h] [:b :e :g])
于 2016-11-21T18:28:21.343 回答
0

filter gives all of the results, where some will only give you the first result, or nil if there aren't any. Oftentimes the same problem can be solved by filtering then taking the first, rather than using some.

于 2016-11-20T21:59:58.333 回答