Stephen Cagle

Menu

  • Home
  • Archives
  • About Me
  • RSS
April 24, 2019

This To That

I need something that converts a particular key/value within a sequence of maps into a single map. this->that will do nicely.

(defn this->that [this that vs]
  "Build a map out of sequence vs; taking `this` as the key and `that` as the value from each"
  (reduce
   (fn [acc v] (assoc acc (this v) (that v)))
   {}
   vs))
;; -> {:key-1 :value-1, :key-2 :value-2}

Let's create some data for this example.

(def data 
  [{:id 1 :email "mouse@hanna-barbera.com" :name "Bullwinkle J. Mouse"}
   {:id 2 :email "squirrel@hanna-barbera.com" :name "Rocky the Flying Squirrel"}
   {:id 3 :email "boris@hanna-barbera.com" :name "Boris Badenov"}
   {:id 4 :email "ffetale@hanna-barbera.com" :name "Natasha Fatale"}
   {:id 5 :email "leader@hanna-barbera.com" :name "Fearless Leader"}])

With this->that and our data, we can now create a map of :id to :email.

(defn id->email [vs]
  (this->that :id :email vs))
(id->email data)

Or :id to :name.

(defn id->name [vs]
  (this->that :id :name vs))
(id->name data)

Interesting

Within this->that the arguments this and that are being called. This must mean that keywords (:id, :email, and :name in our case) are callable as functions! this->that actually takes two functions as the this and that arguments. this->that can take a sequence of any type in vs, provided that you can write functions to pull values from every element in vs.

Let's illustrate the equivalency of keywords and functions below.

(= (this->that :id :name data)
   (this->that #(:id %) #(:name %) data))

« Quick Containment in a Arbitrary Depth Map Hellboy (2019) »

Copyright © 2020 Stephen Cagle