Hello. Newbie question, how can I get this to still match on the keys that do exist in my input and simply ignore the ones that doesn't exist?
(m/rewrite
[{:name {:first "jon"
:OOPS {:family "doe"}}}]
[{:name {:first !first
:last {:family !last}}} ...]
[{:my-name {:my-first !first
:my-last !last}} ...])
I'm expecting:
[{:my-name {:my-first "jon"}}]
or
[{:my-name {:my-first "jon", :my-last nil}}]
but instead the whole result is nil
Thanks!In your example, [{:name {:first !first :last {:family !last}}} ...] is the pattern, and so the whole map structure must be present to match
Let me play around a minute, I may be missing some context...
Yeah, because this is happening in a submap, that makes the :last key essentially required to match
There are several ways to deal with this, but perhaps the most straightforward (if obtuse) would be to add an additional clause:
(m/rewrite
[{:name {:first "jon"
:OOPS {:family "doe"}}}]
[{:name {:first !first
:last {:family !last}}} ...]
[{:my-name {:my-first !first
:my-last !last}} ...]
[{:name {:first !first}} ...]
[{:my-name {:my-first !first
:my-last nil}} ...])But you can also use recursion to break the pattern down into the sequence and map parts:
(m/rewrite
[{:name {:first "jon"
:last {}}}
{:foo "x"}]
{:name {:first ?first
:last {:family ?last}}}
{:my-name
{:my-first ?first
:my-last ?last}}
{:name {:first ?first}}
{:my-name
{:my-first ?first
:my-last nil}}
[(m/cata !maps) ...]
[!maps ...])Finally, you can condense the 2 clauses into 1 by explicitly making the optional :last key nilable:
(m/rewrite
[{:name {:first "jon"
:OOPS {}}}]
{:name {:first ?first
:last (m/or {:family ?last}
(m/and nil ?last))}}
{:my-name
{:my-first ?first
:my-last ?last}}
[(m/cata !maps) ...]
[!maps ...])Thank you for providing some options, I'll play around with it tomorrow. 🙏🏻
Works great!