1
$\begingroup$

I have a list of rules resembling

rules = {{a -> {1, 2, 3}}, {b -> {2, 3, 4}}, {c -> {3, 4, 5}, c -> {4, 5, 6}}}

How can I neatly rearrange this to get a list of rules where they keys only occur once, and all their respective values are joined together? Desired output

{a -> {1, 2, 3}, b -> {2, 3, 4}, c -> {3, 4, 5, 6}}

I have what I think is an inelegant approach:

Flatten[
    GatherBy[rules, Keys] /.
        {r__Rule} :> Rule[First @ Keys[{r}], Union @@ Values[{r}]]
]

(* {a -> {1, 2, 3}, b -> {2, 3, 4}, c -> {3, 4, 5, 6}} *)

Is there a better way of doing this?

$\endgroup$
1
$\begingroup$
Merge[{rules}, Union @@ # &]

<|a -> {1, 2, 3}, b -> {2, 3, 4}, c -> {3, 4, 5, 6}|>

You can either continue to use this Association (this works indeed, e.g., with ReplaceAll) or you can convert back to a list of rules with Normal.

$\endgroup$
  • $\begingroup$ And here I was thinking Merge only worked with associations... Much obliged. $\endgroup$ – user170231 Jan 31 at 18:22
  • $\begingroup$ You're welcome. $\endgroup$ – Henrik Schumacher Jan 31 at 18:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.