Fork me on GitHub
#meander
<
2022-06-14
>
dmegas19:06:35

Hello all! I’m pretty new to meander and I’m stuck trying to do the following (contrived example in thread):

dmegas19:06:21

Given an input of the form

(def input {:result {:brands-list {:items [{:url   ""
                                              :image ""
                                              :id    "52845"}]}
                       :products-list
                       [{:name    "Product A"
                         :brand-id "1173500"
                         :price   "33.00"}
                        {:name    "Product B"
                         :brand-id "52845"
                         :price   "20.65"}]}})

dmegas19:06:45

I’d like to get the product info like follows:

({:product-name "Product B",
    :brand-id "52845",
    :brand-url "",
    :product-price "20.65"}
   {:product-name "Product A",
    :brand-id "1173500",
    :brand-url nil,
    :product-price "33.00"})

dmegas19:06:41

The tricky thing I can’t get to work is to get a “brand”’s :url if the product’s :brand-id matches one of the :id s in :brands-list but leave it blank otherwise.

dmegas19:06:05

Trying with

(defn products
    [input]
    (m/search input

              {:result {:brands-list   {:items (m/scan {:url ?brand-url
                                                        :id  ?brand-id})}
                        :products-list (m/scan {:name    ?product-name
                                                :brand-id ?brand-id
                                                :price   ?product-price})}}
              {:product-name ?product-name
               :brand-id ?brand-id
               :brand-url ?brand-url
               :product-price ?product-price}))
I’m only able to get the product with a matching brand-id
(products input) => ({:product-name "Product B",
  :brand-id "52845",
  :brand-url "",
  :product-price "20.65"})

dmegas19:06:15

Is there a way to accomplish what I’m after?

Richie02:06:39

https://github.com/noprompt/meander/issues/137 might help you. Sorry if that's not much help; it's late and I'm logging off.

dmegas08:06:07

thank you, this was helpful indeed! It is working with a combination of m/or and m/let

(defn products
    [input]
    (m/search input

              {:result {:products-list (m/scan {:name    ?product-name
                                                :brand-id ?brand-id
                                                :price   ?product-price})
                        :brands-list   {:items (m/or (m/scan {:url ?brand-url
                                                              :id  ?brand-id})
                                                     (m/let [?brand-url nil]
                                                       (m/not (m/scan {:id ?brand-id}))))}}}
              {:product-name ?product-name
               :brand-id ?brand-id
               :brand-url ?brand-url
               :product-price ?product-price})) 

dmegas08:06:55

The only thing is that I had to change the keys in the pattern, :products-list first and then :brands-list . Otherwise it fails with Unable to resolve symbol: ?brand-id in this context, not sure if there is another way that works with the initial order.