@@ -860,6 +860,48 @@ defmodule Map do
860860 drop_keys ( rest , delete ( acc , key ) )
861861 end
862862
863+ @ doc """
864+ Drops the given `keys` from `map`.
865+
866+ If `keys` contains keys that are not in `map`, an error is raised.
867+
868+ ## Examples
869+
870+ iex> Map.drop!(%{a: 1, b: 2, c: 3}, [:b, :c])
871+ %{a: 1}
872+
873+ iex> Map.drop!(%{a: 1, b: 2, c: 3}, [:b, :d])
874+ ** (KeyError) key :d not found in:
875+ ...
876+
877+ """
878+ @ doc since: "1.20.0"
879+ @ spec drop! ( map , [ key ] ) :: map
880+ def drop! ( map , keys )
881+
882+ def drop! ( map , keys ) when is_map ( map ) and is_list ( keys ) do
883+ drop_keys! ( keys , map )
884+ catch
885+ key ->
886+ raise KeyError , key: key , term: map
887+ end
888+
889+ def drop! ( non_map , keys ) when is_list ( keys ) do
890+ :erlang . error ( { :badmap , non_map } , [ non_map , keys ] )
891+ end
892+
893+ defp drop_keys! ( [ ] , acc ) do
894+ acc
895+ end
896+
897+ defp drop_keys! ( [ key | rest ] , acc ) when is_map_key ( acc , key ) do
898+ drop_keys! ( rest , delete ( acc , key ) )
899+ end
900+
901+ defp drop_keys! ( [ key | _ ] , _acc ) do
902+ throw ( key )
903+ end
904+
863905 @ doc """
864906 Takes all entries corresponding to the given `keys` in `map` and extracts
865907 them into a separate map.
0 commit comments