Proposal: Add Enum.index_by/2

61 views
Skip to first unread message

Tobias Pfeiffer

unread,
May 8, 2022, 9:24:16 AM5/8/22
to elixir-l...@googlegroups.com
Hello everyone,

I'd like to propose `Enum.index_by/2` (or potentially /3, see further down).

Essentially, it is supposed to be same thing was `Enum.group_by/3` but without putting the values into a list - so one key, one item.

It is inspired by the Rails Enumerable method of the same name [1].

Now, why should we have this?

I believe the use case, while not super common, is common enough and valid. Most often I see it when you have 2 different collections of data and you want to stitch them together. For instance, you have accounts of your users on another platform and you want to associate your users to those accounts - so you fetch your users, index them by their email as a key and then you can go through the other list effectively fitting them together with your user. Or take payment transactions in an external payment system and payment transactions as tracked in your application.

I'm not aware of a "nice" way to do this in Elixir right now. The "best" would probably be `Map.new/2` although most often I see people fall back to `Enum.reduce/3` which I consider sub optimal for most cases (thankfully most common usages of `Enum.reduce/3` usually have a better equivalent in the language itself).

While `Enum.group_by/2` does most of what I want here, transforming all the one element lists into just the element to easily work with it is somewhat annoying.

Speaking of which, it might be fair to say that if we want to do this we'd want `Enum.index_by/3` to mirror `Enum.group_by/3` (with an optional value function) which sounds good to me.

Happy to tackle the implementation myself.

Thank you + cheers,
Tobi


PS: Have a bunny

IMG_20220130_140748_Bokeh.jpg

Adam Lancaster

unread,
May 8, 2022, 9:31:34 AM5/8/22
to elixir-l...@googlegroups.com
Map.new is the right approach in my humble opinion, i’m not sure what index_by would add over that. Keen to hear other opinions though.

The function proposed sounds more like “group_by_index” to me but that’s just me.

Best
Adz

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAG3Z5YR3rQL4kcNFACj59i6t7GuBHN34bGCubQ6V8diG47ePLg%40mail.gmail.com.

José Valim

unread,
May 8, 2022, 10:39:57 AM5/8/22
to elixir-lang-core
I think a code snippet here would help but it does feel like Map.new does most of the job:

    Map.new(collection, &{&1.email, &1})

I am not convinced about the name index_by. I understand the meaning of index here, but it is not what index means in Enum (i.e. an integer).

Aaron Ross

unread,
May 8, 2022, 9:59:45 PM5/8/22
to elixir-lang-core
I’ve seen this referred to as `key_by` in a few other contexts, such as lodash. When I was first learning Elixir from a JS background, I recall looking for a comparable function in Enum a few times, but I believe the `Map.new/2` approach is idiomatic.

Kurtis Rainbolt-Greene

unread,
May 18, 2022, 12:11:06 PM5/18/22
to elixir-l...@googlegroups.com



--
Kurtis Rainbolt-Greene,
Software Developer & Founder of Difference Engineers
Reply all
Reply to author
Forward
0 new messages