2012-05-16 37 views
10

マップから値を使ってキーを抽出する必要があります。逆引き参照を自分で実装する以外にこれを行う方法はありますか?逆引き参照

+3

私は何ですか? f 2以上のキーの値が同じですか?それらのうちの1つ、またはそれらのすべてが必要ですか? – ivant

答えて

3

(some #(if (= (val %) your-val) (key %)) your-map) 
6

あなたは2ライン機能と、本当に簡単にマップを逆にすることができます:

(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 
+1

注:すべての集中的な目的のために、マップ '{:a 1:b 1} 'は何が定義されていません。 – Jeremy

+0

@Jeremy:厳密には定義されていないので、 '{1:a}'や '{1:b}'の逆参照を確実に取得します(ハッシュマップの内部順序に依存します)。しかし、価値が重複している場合は、おそらくこれに特別な扱いをしたいと思います。 – mikera

+0

うん。私が意味したのは、それが依拠されるべきではないということでした。また、PersistentArrayMapsである小さなマップは、PersistentHashMapに強制されるまで*予測可能な*(必ずしも必要ではない)動作を持つことができます。しかし、再び、それは信頼されるべきではありません。 – Jeremy

0

に別のものを試してみてください。

(defn reverse-map [m]                               
    (apply hash-map (mapcat reverse m))) 

(defn reverse-lookup [m k]                              
    (ffirst (filter (comp #{k} second) m))) 
25

私はmap-invertが正しいことだと思いますこれを行う方法。

From the docs:

;; 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. 
1

あなたはClojureScriptを使用しているか、代わりの1以上を必要とする場合:)

(zipmap (vals m) (keys m))

0

あなたが鍵を保持したい場合は、それだけでマップを反転することをお勧めしますしかし、セット/リストなどの古いキーを収集する...

(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)) 
関連する問題