Fork me on GitHub
#meander
<
2020-04-23
>
grounded_sage14:04:01

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)}))

Jimmy Miller16:04:14

Do you actually need search semantics for some bigger part of this. Or are you okay with it being a match?

Jimmy Miller16:04:02

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})

grounded_sage17:04:32

Iā€™m having some internet troubles atm so have to reply on phone. What would you do if :Price itself is missing?

noprompt17:04:35

The answer @U5K8NTHEZ gave accounts for that :Price , (m/or {,,,} (m/let [,,,]))

noprompt17:04:10

So either :Price is a map and you bind the values, or you m/let them out.

šŸ‘ 4
grounded_sage17:04:56

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

Jimmy Miller18:04:43

Yeah sorry I missed all the other ones. I will try to write that up as well.

Jimmy Miller19:04:14

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.