Do you think a join
option would be a good idea for comprehensions?
Something like Enum.map_join/2
that could map and join lists in a single pass.
book_ids = for book <- books, join: ",", do: book.id
If it looks like a good idea, I will open a ticket / PR.
1 Like
Eiji
June 20, 2022, 2:15pm
2
Well … decision on adding features and enhancements is up to @Elixir-Core-Team . What I can say is that you can already do that in a single pass using reduce
option:
# Here is a simplified list
books = [%{id: 1}, %{id: 2}, %{id: 3}, %{id: 4}, %{id: 5}]
# Here is an example comprehension:
book_ids = for book <- books, reduce: "" do
"" -> book.id
acc -> "#{acc}.#{book.id}"
end
Helpful resource:
:reduce option in Kernel.SpecialForms.for/1
4 Likes
Yes I’m a big fan of reduce
in comprehensions.
Was just wondering if a :join
option would be useful or software bloat
You could write your own Collectable
module and use :into
to achieve this if you expect to use it often.
1 Like
There is always that question.
[%{id: 1}, %{id: 2}, %{id: 3}, %{id: 4}, %{id: 5}]
|> Enum.map_join(",", fn %{id: id} -> id end)
"1,2,3,4,5"
As the for comprehension is seen by some as a mapper, I can see how there could be a :join variant for for comprehensions.
ps. Now I have written this example I wonder why map_join is a separate function instead of Enum.join/3
Enum.map_join
is able to map & join in a single pass, whereas calling Enum.map
then Enum.join
would require two successive loops.
adamu
June 20, 2022, 6:42pm
7
I think he means why doesn’t join
take a function that’ll also map it for you, like into
, or Map.new
does?
2 Likes
My guess would be because there already is a joiner
optional argument, adding an extra optional mapper
argument would have made it awkward to use?
join(enumerable, joiner \\ "", mapper \\ fn x -> x end)