I'm looking for something similar to select-keys:
(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
It's not particularly hard to implement, though I haven't tried to come up with a good name yet:
(defn select-values-corresponding-to-keys [m ks]
(for [k ks]
(get m k)))
Am I ignorant of a standard function that meets precisely this need? If not, do other languages —e.g., Python, Ruby, Haskell— have a name for this function?
Maps are functions which operate on their keys:
({: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
If you want the result as a vector, just use vec
or into [] ...
, or replace map
with mapv
.
Keywords are themselves functions (they implement IFn
) and they can look themselves into a map and return the value so one option would be to use 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}))
So basically your desired fn now becomes:
(defn select-vals [map keys] ((apply juxt keys) map))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With