@@ -214,7 +214,24 @@ defmodule Map do
214214
215215 """
216216 @ spec new ( Enumerable . t ( ) , ( term -> { key , value } ) ) :: map
217- def new ( enumerable , transform ) when is_function ( transform , 1 ) do
217+ def new ( enumerable , transform )
218+ def new ( % _ { } = enumerable , transform ) , do: new_from_enum ( enumerable , transform )
219+ def new ( % { } = map , transform ) , do: new_from_map ( map , transform )
220+ def new ( enumerable , transform ) , do: new_from_enum ( enumerable , transform )
221+
222+ defp new_from_map ( map , transform ) when is_function ( transform , 1 ) do
223+ iter = :maps . iterator ( map )
224+ next = :maps . next ( iter )
225+ :maps . from_list ( do_map ( next , transform ) )
226+ end
227+
228+ defp do_map ( :none , _fun ) , do: [ ]
229+
230+ defp do_map ( { key , value , iter } , transform ) do
231+ [ transform . ( { key , value } ) | do_map ( :maps . next ( iter ) , transform ) ]
232+ end
233+
234+ defp new_from_enum ( enumerable , transform ) when is_function ( transform , 1 ) do
218235 enumerable
219236 |> Enum . map ( transform )
220237 |> :maps . from_list ( )
@@ -972,104 +989,21 @@ defmodule Map do
972989 map_size ( map )
973990 end
974991
975- @ doc """
976- Returns a map containing only those pairs from `map`
977- for which `fun` returns a truthy value.
978-
979- `fun` receives the key and value of each of the
980- elements in the map as a key-value pair.
981-
982- See also `reject/2` which discards all elements where the
983- function returns a truthy value.
984-
985- > Note: if you find yourself doing multiple calls to `Map.map/2`
986- > and `Map.filter/2` in a pipeline, it is likely more efficient
987- > to use `Enum.map/2` and `Enum.filter/2` instead and convert to
988- > a map at the end using `Map.new/1`.
989-
990- ## Examples
991-
992- iex> Map.filter(%{one: 1, two: 2, three: 3}, fn {_key, val} -> rem(val, 2) == 1 end)
993- %{one: 1, three: 3}
994-
995- """
996- @ doc since: "1.13.0"
997- @ spec filter ( map , ( { key , value } -> as_boolean ( term ) ) ) :: map
998- def filter ( map , fun ) when is_map ( map ) and is_function ( fun , 1 ) do
999- iter = :maps . iterator ( map )
1000- next = :maps . next ( iter )
1001- :maps . from_list ( do_filter ( next , fun ) )
1002- end
1003-
1004- defp do_filter ( :none , _fun ) , do: [ ]
1005-
1006- defp do_filter ( { key , value , iter } , fun ) do
1007- if fun . ( { key , value } ) do
1008- [ { key , value } | do_filter ( :maps . next ( iter ) , fun ) ]
1009- else
1010- do_filter ( :maps . next ( iter ) , fun )
1011- end
1012- end
1013-
1014- @ doc """
1015- Returns map excluding the pairs from `map` for which `fun` returns
1016- a truthy value.
1017-
1018- See also `filter/2`.
1019-
1020- ## Examples
1021-
1022- iex> Map.reject(%{one: 1, two: 2, three: 3}, fn {_key, val} -> rem(val, 2) == 1 end)
1023- %{two: 2}
1024-
1025- """
1026- @ doc since: "1.13.0"
1027- @ spec reject ( map , ( { key , value } -> as_boolean ( term ) ) ) :: map
1028- def reject ( map , fun ) when is_map ( map ) and is_function ( fun , 1 ) do
1029- iter = :maps . iterator ( map )
1030- next = :maps . next ( iter )
1031- :maps . from_list ( do_reject ( next , fun ) )
1032- end
1033-
1034- defp do_reject ( :none , _fun ) , do: [ ]
1035-
1036- defp do_reject ( { key , value , iter } , fun ) do
1037- if fun . ( { key , value } ) do
1038- do_reject ( :maps . next ( iter ) , fun )
1039- else
1040- [ { key , value } | do_reject ( :maps . next ( iter ) , fun ) ]
1041- end
992+ @ doc false
993+ @ deprecated "Use Enum.filter/2 instead"
994+ def filter ( map , fun ) when is_map ( map ) do
995+ Enum . filter ( map , fun ) |> :maps . from_list ( )
1042996 end
1043997
1044- @ doc """
1045- Maps the function `fun` over all key-value pairs in `map`
1046-
1047- It returns a map with all the values replaced with the result
1048- of the function.
1049-
1050- > Note: if you find yourself doing multiple calls to `Map.map/2`
1051- > and `Map.filter/2` in a pipeline, it is likely more efficient
1052- > to use `Enum.map/2` and `Enum.filter/2` instead and convert to
1053- > a map at the end using `Map.new/1`.
1054-
1055- ## Examples
1056-
1057- iex> Map.map(%{1 => "joe", 2 => "mike", 3 => "robert"}, fn {_key, val} -> String.capitalize(val) end)
1058- %{1 => "Joe", 2 => "Mike", 3 => "Robert"}
1059-
1060- """
1061- @ doc since: "1.13.0"
1062- @ spec map ( map , ( { key , value } -> value ) ) :: map
1063- def map ( map , fun ) when is_map ( map ) and is_function ( fun , 1 ) do
1064- iter = :maps . iterator ( map )
1065- next = :maps . next ( iter )
1066- :maps . from_list ( do_map ( next , fun ) )
998+ @ doc false
999+ @ deprecated "Use Enum.reject/2 instead"
1000+ def reject ( map , fun ) when is_map ( map ) do
1001+ Enum . reject ( map , fun ) |> :maps . from_list ( )
10671002 end
10681003
1069- defp do_map ( :none , _fun ) , do: [ ]
1070-
1071- defp do_map ( { key , value , iter } , fun ) do
1072- new_value = fun . ( { key , value } )
1073- [ { key , new_value } | do_map ( :maps . next ( iter ) , fun ) ]
1004+ @ doc false
1005+ @ deprecated "Use Map.new/2 instead"
1006+ def map ( map , fun ) when is_map ( map ) do
1007+ new ( map , fn { k , v } -> { k , fun . ( { k , v } ) } end )
10741008 end
10751009end
0 commit comments