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.
