Proposal: Add Enum.sort_by_transform/4

41 views
Skip to first unread message

eksperimental

unread,
May 4, 2022, 4:09:19 PM5/4/22
to elixir-l...@googlegroups.com
Hi group.
When working on sorting some data I realized that after sorting the
enumerable, I had to map and iterate again to do a data transformation
of the elements.

So I look for a function that would already do this and I cannot find
it. So by looking at the source code
https://github.com/elixir-lang/elixir/blob/1907914cf0d9d25b32373d3c8ad6b4b59877baaf/lib/elixir/lib/enum.ex#L3213-L3218
I see that it is already mapping after the sorting, in order to
return the original values.
So we are unnecessarily mapping once.

What I propose is introduce Enum.sort_by_transform/4 which takes a
transformer function and applies it to each element in the last map
iteration.

> sort_by_transform(enumerable, mapper, transformer, sorter)
>
> Sorts the mapped results of the `enumerable` according to
> the provided `sorter` function and later each element is tranformed
> by applying the `transformer` function. >>

After I'm done with the implementation I see in the documentation I
found that a new section has been added to the docs, (due to the
introduction of `List.keysort/3` in the development version of Elixir.
https://hexdocs.pm/elixir/main/Enum.html#sort_by/3-performance-characteristics

Coincidentally, the more performant solution that I proposes here does
exactly what the implementation of Enum.sort_by_transform/4 does.
https://github.com/eksperimental/elixir/commit/77c7bcea9348c0dfb16d0e94b2b5ba9d239a3cd5#diff-9a538f965f1fdc2cf9780b1008560f05bfa2ff80d145445abe37a0d70d3828a2R3219-R3230

So the example in the guide could be simplified as (after removing
the filtering of the id of the products, to make the example easier to
grasp)

Enum.sort_by_transform(products, & &1.price, & &1.name)

Additionally (and optionally) I introduce Enum.map_sort_by/3 which
solves the common case of mapping and sorting in one go.
For example to sort the products alphabetically:

Enum.map_sort_by(products, & &1.name)

You can see the full implementation here:
https://github.com/elixir-lang/elixir/compare/main...eksperimental:sort_by_transform


Please, let me know what you all think.

José Valim

unread,
May 4, 2022, 4:20:57 PM5/4/22
to elixir-l...@googlegroups.com
Hi, thanks for the proposal!

We have added list keysort Exactly for use cases like this, So given the new functions are wrappers around keysort and given the new docs, I would push people towards using keysort first.

--
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/6272dd6b.1c69fb81.94f35.199eSMTPIN_ADDED_MISSING%40gmr-mx.google.com.
Reply all
Reply to author
Forward
0 new messages