@@ -214,7 +214,24 @@ defmodule Map do
214
214
215
215
"""
216
216
@ 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
218
235
enumerable
219
236
|> Enum . map ( transform )
220
237
|> :maps . from_list ( )
@@ -972,104 +989,21 @@ defmodule Map do
972
989
map_size ( map )
973
990
end
974
991
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 ( )
1042
996
end
1043
997
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 ( )
1067
1002
end
1068
1003
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 )
1074
1008
end
1075
1009
end
0 commit comments