Reputation: 11
I have a map like this
(def invoice
{:productId ["001" "002" "003" "004" "005" "006" "007" "008" "009" "010"],
:price ["50" "60" "70" "50" "40" "45" "55" "90" "50" "70"],
:quantity ["0" "0" "1" "2" "0" "0" "0" "0" "0" "1"]})
how can i filter so it only show product id where the quantity is 1 or more ?
i already tried to make like this
(filter (> (invoice :quantity %) 1) (map list (invoice :price) (invoice :quantity) (invoice :productid))
but it doesn't work
Upvotes: 1
Views: 539
Reputation: 41
Usually, data is easier to deal with when it's a little more 'normal' so you don't have to worry about indices like in your sample. I'd reccomend storing it as a seq of ({:id x :price y :quant z} ... ).
This function does that:
(defn invoices [invoice]
(map (fn [id price quant]
{:id id
:price price
:quant quant}) (:prouctId invoice)
(:price invoice)
(:quantity invoice))
Then from there you can simply
(->> invoice
invoices
(remove #(= "0" (:price %)) ;; remove "0" prices
(map :id))) ;; get ids
assuming that your dataset doesn't have negative quantities.
Upvotes: 0
Reputation: 1884
first step would be construct a pair of Product ID and quantity:
(map vector (invoice :quantity) (invoice :productId))
;; ["0" "001"] .... first element would be quantity and second is productiID
second step would be filter out which quantity is greater than 0, here I use (Integer. xx) to conver the quantity to a number.
(filter #(> (Integer. (first %)) 0) (map vector (invoice :quantity) (invoice :productId)))
Upvotes: 1
Reputation: 144136
You need to create a function to pass as the first argument to filter
. Secondly, you need to parse the quantities before you do the comparison to 1, which you can do using read-string
:
(filter #(> (read-string (second %)) 1) (map list (invoice :price) (invoice :quantity) (invoice :productId)))
Upvotes: 2