Ich muss einen Schlüssel aus einer Karte mit einem Wert extrahieren. Gibt es eine Möglichkeit, dies zu tun, außer Reverse Lookup selbst zu implementieren?Reverse Lookup in einer Karte
Antwort
(some #(if (= (val %) your-val) (key %)) your-map)
Sie eine Karte wirklich leicht mit einer 2-Linien-Funktion rückgängig machen kann:
(defn reverse-map [m]
(into {} (map (fn [[a b]] [b a]) m)))
(def a {:a 1 :b 2 :c 3})
(reverse-map a)
=> {1 :a, 3 :c, 2 :b}
((reverse-map a) 1)
=> :a
Hinweis: Die Map '{: a 1: b 1}' wird für alle intensiven Zwecke undefiniert. – Jeremy
@ Jeremy: Es ist nicht streng undefiniert, Sie erhalten zuverlässig eine Reverse-Lookup von entweder '{1: a}' oder '{1: b}' (welche Sie erhalten hängt von der internen Reihenfolge der hashmap). Aber ich stimme zu, dass Sie, wenn Sie doppelte Werte haben, dies wahrscheinlich etwas speziell behandeln möchten. – mikera
Ja. Alles, was ich meinte, war, dass man sich nicht darauf verlassen sollte. Außerdem können kleine Maps, die PersistentArrayMaps sind, * vorhersagbares * (nicht unbedingt erwartetes) Verhalten haben, bis sie in eine PersistentHashMap umgewandelt werden. Aber darauf sollte man sich nicht verlassen. – Jeremy
ein noch einmal zu versuchen:
(defn reverse-map [m]
(apply hash-map (mapcat reverse m)))
(defn reverse-lookup [m k]
(ffirst (filter (comp #{k} second) m)))
Ich denke, dass map-invert
das Recht ist Weg, dies zu tun.
;; Despite being in clojure.set, this has nothing to do with sets.
user=> (map-invert {:a 1, :b 2})
{2 :b, 1 :a}
;; If there are duplicate keys, one is chosen:
user=> (map-invert {:a 1, :b 1})
{1 :b}
;; I suspect it'd be unwise to depend on which key survives the clash.
Wenn Sie ClojureScript verwenden oder benötigen Sie eine weitere Alternative :)
(zipmap (vals m) (keys m))
, wenn Sie die Schlüssel halten wollen, ist es besser, nur die Karte invertieren , aber sammeln Sie die alten Schlüssel in einem Set/in einer Liste usw.
(defn map-inverse [m]
(reduce (fn [m' [k v]] (update m' v clojure.set/union #{k})) {} m))
(defn map-inverse [m]
(reduce (fn [m' [k v]] (update m' v conj k)) {} m))
Was ich f 2 oder mehr Tasten haben den gleichen Wert? Brauchst du nur einen oder alle? – ivant