@@ -214,24 +214,7 @@ defmodule Map do
214
214
215
215
"""
216
216
@ spec new ( Enumerable . t ( ) , ( term -> { key , value } ) ) :: map
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
217
+ def new ( enumerable , transform ) when is_function ( transform , 1 ) do
235
218
enumerable
236
219
|> Enum . map ( transform )
237
220
|> :maps . from_list ( )
@@ -989,16 +972,73 @@ defmodule Map do
989
972
map_size ( map )
990
973
end
991
974
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 ( )
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.filter/2`
986
+ > and `Map.reject/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 ) )
996
1002
end
997
1003
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 ( )
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
1002
1042
end
1003
1043
1004
1044
@ doc false
0 commit comments