How do I do this where :Price
is an optional key. I have certain JSON files where say :Price
or perhaps :Name
inside of :Price
is missing. I want to still match on the file and offer a default value
(defn data-transform
[data]
(m/search data
{:Data {:Tickets (m/scan {:Seat ?seat
:Eventname ?event-name
:Price {:Name ?price-name
:Amount ?price-amount}})}}
{:seat ?seat
:ticket-category (or ?price-name nil)
:price (or ?price-amount nil)}))
Do you actually need search semantics for some bigger part of this. Or are you okay with it being a match?
Actually I can make it work with search.
(m/search data
{:Data {:Tickets (m/scan {:Seat ?seat
:Eventname ?event-name
:Price (m/or
{:Name ?price-name
:Amount ?price-amount}
(m/let [?price-name "default-name"
?price-amount "default-price"]
nil))})}}
{:seat ?seat
:ticket-category ?price-name
:price ?price-amount})
Iām having some internet troubles atm so have to reply on phone. What would you do if :Price itself is missing?
The answer @jimmy gave accounts for that :Price
, (m/or {,,,} (m/let [,,,]))
So either :Price
is a map and you bind the values, or you m/let
them out.
I actually think the solution you gave me will be sufficient. But I am curious as to how one would handle missing data like I described
Yeah sorry I missed all the other ones. I will try to write that up as well.
I should explain the steps on how I got here, but I already wasted too much time playing with this š
(m/defsyntax with-defaults [bindings body]
(m/rewrite bindings
[!binding (m/and !lvar1 !lvar2) !default ...]
('m/with [!binding ('m/or ('m/some !lvar1)
('m/let [!lvar2 !default] nil))
...]
~body)
))
(m/search data
(with-defaults [%name ?name "name"
%amount ?amount 0]
{:Data {:Tickets (m/scan {:Seat ?seat
:Eventname ?event-name
:Price (m/or
{:Name %name
:Amount %amount}
(m/and nil
%name
%amount))})}})
{:seat ?seat
:ticket-category ?name
:price ?amount})
Doing it all inline was getting too verbose. So I made my own little defsyntax thing.