2013-08-11 43 views
7

Tôi là một lập trình viên clojure mới.Clojure lấy khóa bản đồ theo giá trị

Với ...

{:foo "bar"} 

Có cách nào để lấy tên của khóa với một giá trị "thanh"?

Tôi đã xem qua các tài liệu bản đồ và có thể thấy cách lấy khóa và giá trị hoặc chỉ có giá trị nhưng không chỉ là khóa. Giúp đánh giá cao!

+4

Chắc chắn, nhưng nó thường có nghĩa là cấu trúc dữ liệu của bạn là lộn ngược. – delnan

+0

Vì vậy, ... http://stackoverflow.com/questions/15595986/swap-keys-and-values-in-a-map? –

+0

Tùy thuộc vào chính xác bạn đang làm gì (có lẽ bạn thay vào đó có thể thay đổi mã tạo bản đồ hoặc bạn cần cả hai hướng), nhưng linh cảm của tôi là: Có. – delnan

Trả lời

18

Có thể có nhiều cặp khóa/giá trị với giá trị "bar". Các giá trị không được băm để tra cứu, trái ngược với khóa của chúng. Tùy thuộc vào những gì bạn muốn đạt được, bạn có thể tra cứu phím với một thuật toán tuyến tính như:

(def hm {:foo "bar"}) 
(keep #(when (= (val %) "bar") 
      (key %)) hm) 

Hoặc

(filter (comp #{"bar"} hm) (keys hm)) 

Hoặc

(reduce-kv (fn [acc k v] 
      (if (= v "bar") 
       (conj acc k) 
       acc)) 
      #{} hm) 

mà sẽ trả về một seq các phím . Nếu bạn biết rằng Vals của bạn là khác biệt với nhau, bạn cũng có thể tạo ra một đảo ngược tra cứu băm-map với

(clojure.set/map-invert hm) 
5
user> (->> {:a "bar" :b "foo" :c "bar" :d "baz"} ; initial map 
      (group-by val) ; sorted into a new map based on value of each key 
      (#(get % "bar")) ; extract the entries that had value "bar" 
      (map key))  ; get the keys that had value bar 
(:a :c) 
Các vấn đề liên quan