I have some nested data structure looking approximately like:
[{:x [{:y [{:z [{:w [!k ...]} ...]} ...]} ...]} ...]
Where !k is a string
I have another which is a map of {(keyword !k) {:data ?data}}
Where I want to produce
[{:x [{:y [{:z [{:w [!k ...] :data ?data} ...]} ...]} ...]} ...]
Turns out to be less simple than I expected
@ben.sless I am weak in understanding
you could give example input -> output and I will have a try with that.
in words:
sequence of maps, in key x there is a sequence of maps ,,, down to key w
In w there is a sequence of strings
I want to take that sequence, use it to lookup in another map where each key maps to a sequence, and assoc this sequence in the same map as w
(m/rewrite [{:a [{:b [{:c ["d" "e" "f"]}]}]}
{:d 1 :e 1 :f 1}]
[{:a [{:b [{:c [(m/app keyword !ks) ...]}]}] :as ?m}
(m/map-of !ks !vs)]
{& [?m [!ks !vs] ...]})
@ben.sless something like that?
yes but all the nested sequences can also repeat
More like
(let [lookup {:a [1 2 3]
:b [4 5 6]
:c [7 8 9]
:H '[x y z]}]
(m/rewrite
{:x
[{:y
[{:z
[{:w ["a" "b"]}
{:w ["c" "d"]}]}
{:z
[{:w ["e" "f"]}
{:w ["g" "h"]}]}]}
{:y
[{:z
[{:w ["A" "B"]}
{:w ["C" "D"]}]}
{:z
[{:w ["E" "F"]}
{:w ["G" "H"]}]}]}]}
{:x [!x ...]}
{:x [(m/cata !x) ...]}
{:y [!x ...]}
{:y [(m/cata !x) ...]}
{:z [!x ...]}
{:z [(m/cata !x) ...]}
{:w [(m/and !x (m/app keyword !k)) ...]}
{:w [!x ...] :k [!k ...] :lookup ~lookup}))
But I'm stuck on the final transition
You can use [!x ..!n] to capture the number of times something repeats. Helps keep those nested repeats in place.
I'll try again and try to see where I bumped against that specific wall, because I started with it
(m/rewrite
{:in [{:x
[{:y
[{:z
[{:w ["a" "b"]}
{:w ["c" "d"]}]}
{:z
[{:w ["e" "f"]}
{:w ["g" "h"]}]}]}
{:y
[{:z
[{:w ["A" "B"]}
{:w ["C" "D"]}]}
{:z
[{:w ["E" "F"]}
{:w ["G" "H"]}]}]}]}]
:look
{:a [1 2 3]
:b [4 5 6]
:c [7 8 9]
:H '[x y z]}}
{:in [{:x [{:y [{:z [{:w [(m/and !s (m/app keyword !k))
..!nk]}
..!nw]}
..!nz]}
..!ny]}
..!nx]
:look {!k [!d ...]}}
[{:x [{:y [{:z [{:w [!s ..!nk]
:d [!d ...]}
..!nw]}
..!nz]}
..!ny]}
..!nx]
)
accumulating the looked-up values doesn't work right, I'm probably missing something
(on my phone). Memory variables don't join like that. You'd want to assign :look to something and do something like (m/app get lookup)
Can't think of the right way right now. But will try to play with it later if I have time at the computer and no one else already solved it.
No pressure
Very close now
(let [lookup {:a [1 2 3]
:b [4 5 6]
:c [7 8 9]
:H '[x y z]}
f (fn [x] (get lookup (keyword x)))]
(m/rewrite
{:x
[{:y
[{:z
[{:w ["a" "b"]}
{:w ["c" "d"]}]}
{:z
[{:w ["e" "f"]}
{:w ["g" "h"]}]}]}
{:y
[{:z
[{:w ["A" "B"]}
{:w ["C" "D"]}]}
{:z
[{:w ["E" "F"]}
{:w ["G" "H"]}]}]}]}
{:x [!x ...]}
{:x [(m/cata !x) ...]}
{:y [!x ...]}
{:y [(m/cata !x) ...]}
{:z [!x ...]}
{:z [(m/cata !x) ...]}
{:w [(m/and !x (m/app f !d)) ...]}
{:w [!x ...] :d [!d ...]}))
Now :d is [[1 2 3] [4 5 6]] for a b and [[7 8 9] nil] for c d
just need to figure out how to... gather?
Aha!
(let [lookup {:a [1 2 3]
:b [4 5 6]
:c [7 8 9]
:H '[x y z]}
f (fn [x] (get lookup (keyword x) []))]
(m/rewrite
{:x
[{:y
[{:z
[{:w ["a" "b"]}
{:w ["c" "d"]}]}
{:z
[{:w ["e" "f"]}
{:w ["g" "h"]}]}]}
{:y
[{:z
[{:w ["A" "B"]}
{:w ["C" "D"]}]}
{:z
[{:w ["E" "F"]}
{:w ["G" "H"]}]}]}]}
{:x [!x ...]}
{:x [(m/cata !x) ...]}
{:y [!x ...]}
{:y [(m/cata !x) ...]}
{:z [!x ...]}
{:z [(m/cata !x) ...]}
{:w [(m/and !x (m/app f [!d ...])) ...]}
{:w [!x ...] :d [!d ...]}))
not a fan of this solution though, so if you come up with something better, please share
Not much but it looks like this works
(m/rewrite
thing
{:w [(m/and !x (m/app f [!d ...])) ...]}
{:w [!x ...] :d [!d ...]}
{(m/and ?k (m/or :x :y :z)) [!x ...]}
{?k [(m/cata !x) ...]})
more concise, less explicit about the shape of the data