2

マップをネストした edn があります。この Clojure の非常に良い例を 1 つ見つけました。ネストされたハッシュマップで 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 に答える