Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing nested values with Specter in Clojure

Suppose that I have a Clojure map like this:

(def mymap {:a [1 2 3] :b {:c [] :d [1 2 3]}})

I would like a function remove-empties that produces a new map in which entries from (:b mymap) that have an empty sequence as a value are removed. So (remove-empties mymap) would give the value:

{:a [1 2 3] :b {:d [1 2 3]}}

Is there a way to write a function to do this using Specter?

like image 811
alanf Avatar asked Feb 04 '23 04:02

alanf


2 Answers

Here's how to do it with Specter:

(use 'com.rpl.specter)

(setval [:b MAP-VALS empty?] NONE my-map)
=> {:a [1 2 3], :b {:d [1 2 3]}}

In English, this says "Under :b, find all the map values that are empty?. Set them to NONE, i.e. remove them."

like image 76
Ben Kovitz Avatar answered Feb 06 '23 17:02

Ben Kovitz


(update my-map :b (fn [b]
                    (apply dissoc b 
                           (map key (filter (comp empty? val) b)))))
like image 33
amalloy Avatar answered Feb 06 '23 17:02

amalloy