Ted
I’m trying to figure out the idiomatic way to group a list of maps by an atom because mix format gives me an interesting result, depending on what I try.
Here’s my input and I’d like to group by :species.
iex(7)> characters = [
...(7)> %{species: :human, name: "Calvin"},
...(7)> %{species: :human, name: "Rosalyn"},
...(7)> %{species: :feline, name: "Hobbes"}
...(7)> ]
My first approach was to be explicit by using Map.get/3:
iex(8)> characters |> Enum.group_by(&Map.get(&1, :species))
%{
feline: [%{name: "Hobbes", species: :feline}],
human: [
%{name: "Calvin", species: :human},
%{name: "Rosalyn", species: :human}
]
}
That looks pretty good.
And then I tried it with a combination of capturing and map.key syntax*, getting the same result. ![]()
iex(9)> characters |> Enum.group_by(&(&1.species))
Now for the interesting part: when the latter example is subjected to mix format the result is:
characters |> Enum.group_by(& &1.species)
To my novice eyes, that (& &1.species) part looks really weird and now I’m thinking I’m barking up the wrong tree. ![]()
I’d appreciate any thoughts. Thanks!
Extra stuff:
I found this (really cool) reply by Jose, but in this case the capture involves a tuple and mix format doesn’t change it:
(* I understand that map.key will raise when Map.get/3 will nil, and therefore they’re not exactly the same.)
Trending in Chat/Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 5- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
benwilson512
Enum.group_by(&(&1.species))is exactly equivalent toEnum.group_by(& &1.species). The parens for&are always optional. The formatter removes them because they’re unnecessary. It doesn’t remove the{}in Jose’s example because those are part of the actual datastructure definition.Ted
Thanks for clarifying, Ben.
(And I’m really looking forward to digging into your book once I get more Elixir fundamentals down. I’ve been writing a fair number of RESTful APIs in Java lately and, well… seeing something new will be very cool.
)
I also took a look at the doc for
Kernel.&/1and that helped solidify the fact that it’s just another macro and nothing magical is going on with the invocation.So, what I gather is that
Enum.group_by(& &1.species)won’t look so weird to me as I continue to develop my Elixir eyes and this is indeed idiomatic.peerreynders
It’s not. The
macrobeside the source link is misleading - the source it links to is a macro but that isn’t what helps to implement the described behaviour:That would generate an error if it evaluated during compilation.
Kernel.SpecialForms:So implementing
Kernel.SpecialForms.&/1is built into the compiler.benwilson512
Well, fundamentally it’s syntatictally a macro, which is what’s relevant here. It follows the same syntax calling rules as other macros in that the formatter can choose to elide parens by default, as it does with
if,def, and other macros.Ted
Thanks for clarifying that it is indeed a special form; I was a little confused by the source that I saw.