Hello! I'm using meander/match for basic data mapping between dto and domain objects. How can I ignore input map fields that have nil value without doing post processing? For now meander matches on these fields and I get keys with nil values on my output map (expected)
@agorglouk again not an expert, but it is worth remembering that the expr argument to m/match is ‘just’ a clojure expressions (AFAIU), so:
(m/match
{:foo 123 :bar nil}
{:foo ?foo
:bar ?bar}
(cond-> {:foo ?foo}
?bar (assoc :bar ?bar)))
you can just check what has been bound to ?bar and decide what to do with it on the expr side, so to speakThat's what I'm doing so far! I was hoping that there is a better, a bit more declarative way to declare this kind of thing near the pattern as this would communicate better the intent
im pretty sure this is :kw (m/not (m/some _))
vanilla poc:
(meander/match
{:foo 123 :bar nil}
{:foo ?foo
:bar ?bar}
{:otherfoo ?foo
:otherbar ?bar})
=> {:otherfoo 123, :otherbar nil}
try with (m/not (m/some)):
(meander/match
{:foo 123 :bar nil}
{:foo ?foo
:bar (m/not (m/some ?bar))}
{:otherfoo ?foo
:otherbar ?bar})
=> Execution error (ExceptionInfo) at ...
non exhaustive pattern match
so this doesn't seem to work(edited poc above)
wouldn't you want something like:
{:foo ?foo :bar (m/not (m/some _))} {:otherfoo ?foo}? this says "if we find foo and bar is nil, remap foo to :otherfoo".
meander might not be what you are looking for. or, at least my knowledge of m/find m/search and m/cata isn't good enough to build the expression.
if any key's value can be nil and you wish to exclude all k-v pairs whose k is nil... that is a combinatorial explosion of matches.
What I want is, foo maps to otherfoo, and if bar not nil, map to otherbar else skip otherbar key from output
I want this rule to be specific for bar
if you want to target a specific key, provide two matcher patterns in the appropriate order.
try to match foo and bar where bar is not nil, then try to match foo and bar where bar is nil. in one case return a map with otherfoo, otherbar. in the other case, only return otherbar.
this doesn't scale well, but can be useful for very small sets of matches. there is probably a better way to do it with the more complicated search/scan/or/cata/rewrite ... but as you've probably noticed, the exception-infos aren't super helpful and the docs are a bit light.
personally, i would do a postprocess step and not try to write a complicated meander expression. something like remove-nil-pairs is trivial to write. you might be able to construct something that does it 'natively' via meander ... but i've found it very hard to do anything but the most basic match-and-rewrite because or, and, scan, search, cata, rewrite gets difficult.
i love meander for transforms/reshaping. but i quickly abort using it (or use a post processing step) for anything beyond the most basic m/match.
Yeah I suppose I need to re-read the docs and try to get a better grasp of it as a whole. We'll see where this leads :)
do let me know if you come up with some great insight. i feel badly because the library is probably awesome, but i haven't been able to crack through the docs and the implementation is hard for me to grok. that said, the most common/basic usage is a huge win imo. the matcher works great as a data-driven, less strict schema/spec/malli.
Will do, thanks for giving it a try!
IIUC, this is pretty simple:
(m/match {:foo 123 :bar nil}
{:foo ?foo :bar nil} {:otherfoo ?foo}
{:foo ?foo :bar ?bar} {:otherfoo ?foo :otherbar ?bar})
=> {:otherfoo 123}