2013-05-28 26 views
8

Tôi đang tìm một cái gì đó tương tự như select-keys:Có một tiêu chuẩn func mà có một dict và một danh sách các phím và trả về danh sách các vals tương ứng?

(desired-fn {:a 1, :b 2, :c 3, :d 4} [:a :d]) 
;= [1 4] 

;; N.B. the order of the keys in the argument seq is preserved 
(= (desired-fn (array-map :a 1, :b 2, :c 3, :d 4) 
       [:b :c]) 
    (desired-fn (array-map :d 4, :c 3, :a 1, :b 2) 
       [:b :c])) 
;= true 

Đó không phải là đặc biệt khó khăn để thực hiện, mặc dù tôi đã không cố gắng để đến với một tên tốt được nêu ra:

(defn select-values-corresponding-to-keys [m ks] 
    (for [k ks] 
    (get m k))) 

Am I không biết gì về một chức năng tiêu chuẩn đáp ứng chính xác nhu cầu này? Nếu không, hãy làm các ngôn ngữ khác — ví dụ: Python, Ruby, Haskell— có tên cho hàm này không?

Trả lời

1

Jay Fields khám phá chức năng này và một vài ứng dụng khác có liên quan trong bài đăng blog sâu sắc @http://blog.jayfields.com/2011/01/clojure-select-keys-select-values-and.html.

(Tôi thấy rằng một cách tình cờ chỉ là một vài phút trước khi tôi tìm kiếm "chọn-chìa khóa".)

tôi vẫn muốn biết nếu có một "kinh điển" thực hiện ở đâu đó, vì vậy tôi để câu hỏi mở ra.

+0

Có thể rõ ràng, có triển khai 'chuẩn' và đó là 'bản đồ'; bất kỳ câu trả lời 'map' nào ở trên đều đúng. 'map' được sử dụng theo cách đó là sự đồng bộ với bài viết của Jay gọi là' các giá trị lựa chọn'. –

10

Maps là chức năng hoạt động trên các phím của họ:

({:a 1, :b 2} :a) 
;=> 1 

(map {:a 1, :b 2, :c 3, :d 4} [:a :d]) 
;=> (1 4) 

(= (map (array-map :a 1, :b 2, :c 3, :d 4) 
      [:b :c]) 
    (map (array-map :d 4, :c 3, :a 1, :b 2) 
      [:b :c])) 
;=> true 

Nếu bạn muốn kết quả như một vector, chỉ cần sử dụng vec hoặc into [] ..., hoặc thay thế map với mapv.

+3

nói cách khác (def mong muốn-fn mapv) – noisesmith

+0

Bạn hoàn toàn đúng rằng một tính năng thanh lịch của Clojure có nghĩa là hàm này không quan trọng để thực hiện. (khi tôi có nhu cầu về 'lựa chọn-giá trị-tương ứng-to-keys', tôi thực sự quyết tâm làm một cái gì đó rất giống nhau.) –

3

Từ khoá là bản thân chức năng (họ thực hiện IFn) và họ có thể trông tự thành một bản đồ và trả về giá trị vì vậy người ta lựa chọn sẽ được sử dụng juxt:

(def keys-to-vals (juxt :b :c)) 
(= (keys-to-vals {:a 1, :b 2, :c 3, :d 4}) 
    (keys-to-vals {:d 4, :c 3, :a 1, :b 2})) 

Vì vậy, về cơ bản fn mong muốn của bạn bây giờ trở thành :

(defn select-vals [map keys] ((apply juxt keys) map)) 
3

map là chức năng bạn đang tìm kiếm:

(map {:a 1 :b 2 :c 3} [:a :c]) 
=> (1 3) 

Điều này hoạt động vì bản thân hashmap hoạt động như một hàm (tức là thực hiện clojure.lang.IFn) trả về giá trị cho bất kỳ khóa nào được cung cấp.

3
user=> ((juxt :a :c) {:a 1 :b 2 :c 3}) 
[1 3] 
Các vấn đề liên quan