This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

## 2022-04-04

## Channels

- # announcements (28)
- # asami (12)
- # aws (3)
- # babashka (69)
- # babashka-sci-dev (34)
- # beginners (52)
- # biff (3)
- # calva (20)
- # clj-kondo (4)
- # cljsrn (4)
- # clojars (1)
- # clojure (90)
- # clojure-czech (2)
- # clojure-europe (33)
- # clojure-nl (11)
- # clojure-norway (35)
- # clojure-seattle (1)
- # clojure-uk (5)
- # clojurescript (87)
- # cursive (10)
- # datascript (5)
- # datomic (35)
- # defnpodcast (1)
- # emacs (8)
- # events (4)
- # fulcro (1)
- # google-cloud (2)
- # graphql (2)
- # hispano (2)
- # honeysql (5)
- # hoplon (2)
- # hugsql (1)
- # jobs (7)
- # kaocha (9)
- # lsp (102)
- # meander (13)
- # observability (7)
- # off-topic (56)
- # overtone (2)
- # pathom (47)
- # podcasts-discuss (1)
- # rdf (30)
- # reagent (16)
- # reitit (1)
- # releases (2)
- # remote-jobs (26)
- # rewrite-clj (10)
- # tools-deps (4)
- # vim (5)
- # vscode (4)
- # xtdb (41)

I'm a bit confused by this interaction:

```
(-> {:a {:b 0.5 :c 0.5}
:b {:c 1}
:c {:a 1}}
(meander/search
(meander/scan [!sources {:c (meander/some _)}])
!sources))
```

the result I get back is `([:a] [:b])`

but I would have expected `([:a :b])`

. I'm tring to find all map keys that contain `:c`

in the submap.
edit: I get why this happens: each search is a separate search, that only finds one source. But how could I find them all?```
(m/find {:a {:b 0.5 :c 0.5}
:b {:c 1}
:c {:a 1}}
(m/gather [!sources {:c (m/some _)}])
!sources)
```

Thanks for the solution, `gather`

was the missing piece, wasn't aware it existed. I'll confess I still have a bit of difficulty in formulating the correct mental plan when I want to write something with meander. Case in point, the original problem I wanted to solve was turning:

```
{:a {:b 0.5 :c 0.5}
:b {:c 1}
:c {:a 1}}
```

into:
```
{:a {:c 1}
:b {:a 0.5}
:c {:a 0.5 :b 1}}
```

(which are two representation of a weighted graph: the first by outgoing edges, the second by incoming edges).
It's still unclear to me how to jump from this solution to the complete one:
I was trying something along the line of:
```
-> {:a {:b 0.5 :c 0.5}
:b {:c 1}
:c {:a 1}}
(meander/find
(meander/gather [!sources {:c (meander/some !weights)}])
{:c [!sources !weights]}))
```

but I don't see how to interleave `!sources`

and `weights`

to make them a map (almost all the combinations I tried return `nil`

). Also, it doesn't seem possible to turn the key `:c`

above in a logical variable. What should I *think*when solving this problem with meander?

```
(-> {:a {:b 0.5 :c 0.5}
:b {:c 1}
:c {:a 1}}
(meander/find
(meander/gather [!sources {:c (meander/some !weights)}])
{:c (zipmap !sources !weights)}))
```

if only I could do this for each key. Maybe the solution is doing that step outside of meander?Re: *thinking*: The problem should be broken down into steps rather than trying to be solved with one rule:

```
;; Step 1.
(m/search {:a {:b 0.5 :c 0.5}
:b {:c 1}
:c {:a 1}}
{?k {?sk ?sv}}
[[?sk ?k] ?sv])
;; =>
([[:b :a] 0.5]
[[:c :a] 0.5]
[[:c :b] 1]
[[:a :c] 1])
;; Step 2.
(reduce
(fn [m [path v]]
(assoc-in m path v))
{}
'([[:b :a] 0.5]
[[:c :a] 0.5]
[[:c :b] 1]
[[:a :c] 1]))
;; =>
{:a {:c 1}
:b {:a 0.5}
:c {:a 0.5 :b 1}}
```

ok, I'm glad that's the solution, as I did something similar in two steps (but didn't have the idea of grouping the keys to use them with `assoc-in`

; brilliant!)
Thank you! 🙂

OK. Sorry, I made a small mistake in the previous post. Here is the corrected `m/rewrite`

version:

```
(m/rewrite [{:a {:b 0.5 :c 0.5}
:b {:c 1}
:c {:a 1}}
{}]
[{?k {?sk ?sv & ?m-k} & ?m-in}
{?sk ?m-ko & ?m-out}]
(m/cata [{?k ?m-k & ?m-in}
{?sk {?k ?sv & ?m-ko} & ?m-out}])
[{?k {?sk ?sv & ?m-k} & ?m-in}
?m-out]
(m/cata [{?k ?m-k & ?m-in}
{?sk {?k ?sv} & ?m-out}])
[_ ?m-out]
?m-out)
;; =>
{:b {:a 0.5}, :c {:b 1, :a 0.5}, :a {:c 1}}
```

Using a step-wise approach:

```
(let [step (fn [pair]
(m/rewrite pair
[{?k {?sk ?sv & ?m-k} & ?m-in}
{?sk ?m-ko & ?m-out}]
[{?k ?m-k & ?m-in}
{?sk {?k ?sv & ?m-ko} & ?m-out}]
[{?k {?sk ?sv & ?m-k} & ?m-in}
?m-out]
[{?k ?m-k & ?m-in}
{?sk {?k ?sv} & ?m-out}]
[_ ?m-out]
?m-out))
init [{:a {:b 0.5 :c 0.5}
:b {:c 1}
:c {:a 1}}
{}]]
(-> init
step ;; => [{:b {:c 1}, :c {:a 1}, :a {:c 0.5}} {:b {:a 0.5}}]
step ;; => [{:c {:a 1}, :a {:c 0.5}, :b {}} {:b {:a 0.5}, :c {:b 1}}]
step ;; => [{:c {:a 1}, :b {}, :a {}} {:b {:a 0.5}, :c {:b 1, :a 0.5}}]
step ;; => [{:b {}, :a {}, :c {}} {:b {:a 0.5}, :c {:b 1, :a 0.5}, :a {:c 1}}]
step))
;; =>
{:b {:c 0.5, :a 0.5},
:c {:a 0.5},
:a {:c 1}}
```

The second case can be handled in the first case with `m/or`

and `m/let`

:

```
(m/rewrite [{:a {:b 0.5 :c 0.5}
:b {:c 1}
:c {:a 1}}
{}]
[{?k {?sk ?sv & ?m-k} & ?m-in}
(m/or {?sk ?m-ko & ?m-out}
(m/let [?m-ko {}] ?m-out))]
(m/cata [{?k ?m-k & ?m-in}
{?sk {?k ?sv & ?m-ko} & ?m-out}])
[_ ?m-out]
?m-out)
;; =>
{:b {:a 0.5}, :a {:c 1}, :c {:b 1, :a 0.5}}
```

This is to demonstrate that you *can* do this kind of thing but not necessarily that you *should* do this kind of thing. 🙂

@meditans `search`

is for finding all possible solutions, `find`

is for finding one (or none). The reason the `search`

returns is `([:a] [:b])`

is because it there are two solutions and `!sources`

is a singleton vector where `!sources`

matched once for each of the solutions. `m/scan`

is sugar for

`(m/seqable & _ <patterns ...> & _)`

The `& _`

on either side of `<patterns ...>`

is the flexible, ambiguous space and `<patterns ...>`

is what is being matched.