Fork me on GitHub

Dear all, I've been playing around with Meander Epsilon a bit, and I've stumbled upon a problem that feels like trivially solvable but I just couldn't break it. So, noobie question. I'm looking to do kinda like a join, and flatten thing on a vector in a nested map... any help would be highly appreciated! (def db {:items [{:id 1 :labels [1 2 3]} {:id 2 :labels [2]} {:id 3 :labels []} {:id 4 :labels nil} {:id 5 }] :labels [{:id 1 :name "one"} {:id 2 :name "two"} {:id 3 :name "three"} {:id 4 :name "four"}]}) (defn flatten-labels [db] ???) ;; => ;; {:items ;; [{:id 1 :labels ["one" "two" "three"]} ;; {:id 2 :labels ["two"]} ;; {:id 3 :labels []} ;; {:id 4 :labels []} ;; {:id 5 :labels []}]}


I'm in a meeting now and going to be grabbing lunch. But will hopefully have some time to play with this after that.


(m/rewrite db
  {:labels ?labels
   :items [{:id !id :labels (m/or nil [!xs ..!n])} ..?m]}
  {:items [{:id !id :labels [(m/cata [!xs ?labels]) ..!n]} ..?m]}
  [?id (m/gather {:id ?id :name !label})] !label)
There is a lot going on here. First we have nested repeating going on. So in order to capture that I used our capturing repeats [!xs ..!n] and ..?m. Then we have to deal with nil, so I used an m/or. But the big thing here is the cata. If you haven't seen cata, it is like recur. So now we have two patterns. We pass back a vector with the id we want to find and then use gather to search for it. I'd recommend changing your labels to be a map of id to string value. But maybe you want to have the possibility of duplicates? If so you could change this to handle this pretty easily too. I know that was a pretty quick description, so feel free to ask and I can describe things in more detail.


There could maybe be a more direct way of doing this, but I definitely can't think of one given the nested repeats going on.


Thanks @U5K8NTHEZ, appreciated! I'll work my way through this and might get back if I'd get lost... 😉