That turns out to actually be worse believe it or not. Reducing a map 
converts it to a list to begin with because there aren't built in map 
iterators. :maps.fold is really must :lists.foldl(:maps.to_list(map)). So 
given a list of key value pairs, it is actually fastest to build an 
intermediary list with just the desired key value pairs, and then call 
`:maps.from_list` on the result. You can read about that and other related 
stuff here: https://github.com/elixir-lang/elixir/pull/4415

As you'll see in that PR, that's actually how Map.take 
works 
https://github.com/elixir-lang/elixir/blob/e26f8de5753c16ad047b25e4ee9c31b9a45026e5/lib/elixir/lib/map.ex#L329.
 
In OTP 19 there's a NIF for take specifically but the point stands. 
Successive Map.put calls are actually suboptimal.

Stepping back a bit, there are a LOT of functions in Enum that logically 
apply to a map. Should we duplicate all of them in Map just to avoid a `|> 
Map.new` function call? 

On Saturday, June 18, 2016 at 4:49:04 PM UTC-4, Filip Haglund wrote:
>
> Here's another implementation, using Enum.reduce, without an intermediate 
> list: 
>
> def map_filter_values(map, func) do
>   Enum.reduce map, %{}, fn {key, val}, acc ->
>     if func.(val) do
>       Map.put(acc, key, val)
>     else
>       acc
>     end
>   end
> end
>
>
> On Saturday, June 18, 2016 at 6:27:07 PM UTC+2, Filip Haglund wrote:
>>
>> I wish there was a Map.filter_values function that would filter on keys 
>> or values, but leave the other one intact. This seems like something that 
>> should be in the standard library.
>>
>> Example implementation of a Map.filter_values that would filter a map 
>> based on its values, leaving the keys intact:
>>
>> @doc """
>> Filter map based on its values, leaving the corresponding keys intact.
>> """
>> @spec map_filter_values(Map.t, (any -> boolean)) :: Map.t
>> def map_filter_values(map, func) do
>>   map |> Enum.filter(fn {_, val} -> func.(val) end) |> Map.new
>> end
>>
>>
>>
>> A corresponding Map.filter_keys would also be nice.
>>
>

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/630020c8-e8b4-4355-9d4f-2092b3cb914d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to