Hey guys, this is my first proposal so please be kind :) I don't know if WE need this functionality, but I certainly needed this so I already developed it. Obviously I'm not that familiar with Elixir yet so it might happen that there is something very simmilar somewhere in the code, but I looked and couldn't find it.
My idea is to "cleanup" lists which have duplicate values, but in a way that will merge the duplicate values (not just ignore them like uniq/1
does) by using given function (one of the params). Please let me know what you think.
Examples:
iex> Enum.merge([1, 2, 3, 3, 2, 1], fn (x, y) -> x + y end)
[2, 4, 6]
# This one is simmilar to `Enum.uniq/1`
iex> Enum.merge([1, 2, 3, 3, 2, 1], fn (x, _y) -> x end)
[1, 2, 3]
iex> Enum.merge_by([{1, :x}, {2, :y}, {1, :z}], fn (x, _) -> x end, fn {x, _} -> x end)
[{1, :x}, {2, :y}]
iex> Enum.merge_by([a: {:tea, 2}, b: {:tea, 2}, c: {:coffee, 1}], fn (x, _) -> x end, fn {_, y} -> y end)
[a: {:tea, 2}, c: {:coffee, 1}]
iex> Enum.merge_by([%{k: "a", v: 1}, %{k: "b", v: 2}, %{k: "a", v: 3}, %{k: "b", v: 4}], fn(t1, t2) -> %{t1 | v: t1.v + t2.v} end, fn s -> s.k end)
[%{k: "a", v: 4}, %{k: "b", v: 6}]
Because I'm new here I already created PR on github which obviously got closed immediately... :) But there is an upside to this, I already implemented this functionality so you can see the examples in more "human-readable" form on github (https://github.com/elixir-lang/elixir/pull/4854/files) to better understand what I wanted to achieve :)
Please let me know if you think this would be useful and maybe if there is no simmilar functionality already!
I can perfectly understand being conservative about new features and I don't mind if this doesn't get accepted because of that. Although your example is a bit different. To be honest, what I tried to achieve felt like a natural extension of Enum.uniq and when I discovered it's not possible to do what I needed I was a bit dissapointed. Your example of this RunLengthEncoder is not really the same case. The solution to the quiz depends on the fact that the letters need to be one after the other and Enum.merge which I suggest takes into account every element of the list.
--
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/ede59498-9bd5-4e94-afd3-6333da85fa2a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Oh thank you, I felt like this should be possible somehow using just the core. As you mentioned yourself there is still a permormance case
--
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/35266cf0-7c8c-435f-8d73-9a621a72b65d%40googlegroups.com.
I can perfectly understand being conservative about new features and I don't mind if this doesn't get accepted because of that. Although your example is a bit different. To be honest, what I tried to achieve felt like a natural extension of Enum.uniq and when I discovered it's not possible to do what I needed I was a bit dissapointed. Your example of this RunLengthEncoder is not really the same case. The solution to the quiz depends on the fact that the letters need to be one after the other and Enum.merge which I suggest takes into account every element of the list.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/84b33056-1ed1-4291-be72-5900e053fccb%40googlegroups.com.--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-core" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-core/NVT7XEMmldo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-co...@googlegroups.com.
Enum.group_map_reduce(list, group_key_fun, map_fun, initial_acc, reducer)
Enum.group_map_reduce([1,1,2,3,5,5,8], &(&1), &(&1), 0, fn _, acc -> acc + 1 end)That would produce:%{1 => 2, 2 => 1, 3 => 1, 5 => 2, 8 => 1}
The problem with what we currently have is that it requires two passes. There's no one-pass solution available via composition.
I spent quite a bit of time trying to get Stream.group_by working (back in my streamz days) so we can compose things like this in a single pass. It was rough, because it results in a stream of streams which makes it very complicated. It requires one process per key, which leads to a lot complexity around supervision/linking/monitoring and is sort of in it's own league compared to the rest of Stream.
Working with RethinkDB I've seen an alternative approach. Rather than have group_by produce a map of keys to lists, it produces a somewhat monadic result. Applying map to a grouped stream doesn't iterate over keys, instead it applies the function to each group of values. It continues to do so until you call ungroup, at which point the result is an ordinary map of keys to lists.
I'll try to find some time to take a stab at that approach, just to see whether it is at all possible.
--
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/CAAHw6C%2BM47dureeMaQNvKEM3jcag8PBwJWrqi7f%3D705i7%2BTe1g%40mail.gmail.com.