Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Given a sequence of maps in Clojure, how to filter for value of a key > (some value)?

I've got a sequence of Clojure maps that looks something like this:

({:date "2000-01-01" :value 123} 
 {:date "2000-01-02" :value 487} 
 ... 
 {:date "2014-05-01" :value 17})

I want to build a function that will return a similarly-structured sequence of maps, but containing only those maps with :date values between e.g. "2005-11-14" and "2007-08-03".

In their current YYYY-MM-DD form, the dates are compare-able so (compare "2000-01-02" "2001-03-04") works as expected. However, I can't work out how to extract the :date values from the sequence and compare them.

I've made it as far as (filter #(> 0 (compare (:date %)) "2099-12-09") data) but can't get any further. Help!

like image 633
monch1962 Avatar asked Mar 19 '23 12:03

monch1962


1 Answers

in Clojure, data structure such as vectors, sets, and maps can be used as a function. That means that if x is a map, you can get the value by something like (x :date). Therefore the following code will do the job.

(def data '({:date "2005-11-13", :value 0}
         {:date "2005-11-15", :value 1}
         {:date "2007-08-02", :value 2}
         {:date "2007-08-04", :value 3}))
(print (filter
         #(and
               (> (compare (% :date) "2005-11-14") 0)
               (< (compare (% :date) "2007-08-03") 0))
         data))

the output will be

({:date 2005-11-15, :value 1} {:date 2007-08-02, :value 2})

EDITED: the following code is slightly better because it gets date from map once per each iteration.

 (print (filter
         #(let [x (% :date)]
           (and
              (> (compare x "2005-11-14") 0)
              (< (compare x "2007-08-03") 0)))
         data))
like image 60
ymonad Avatar answered Apr 06 '23 00:04

ymonad