pattern-matching - probar - expresiones regulares java pdf
Función de coincidencia de patrón contra el mapa vacío (3)
Estoy jugando con el patrón de coincidencia y descubrí que no es fácil modelar los parámetros de coincidencia de un método contra un mapa vacío. Pensé que sería algo como esto:
defmodule PatternMatch do
def modify(%{}) do
%{}
end
def modify(map) do
# expensive operation
%{ modified: "map" }
end
end
Pero parece que la primera cláusula de función coincide con los mapas arbitrarios:
iex> PatternMatch.modify(%{a: "map"})
==> %{}
¿Hay alguna otra forma de verificar los mapas vacíos?
Además de la respuesta de @ PatrickOscity (que usaría para un mapa vacío), puede usar map_size/1 guard para que coincida con los mapas con varias teclas:
defmodule PatternMatch do
def modify(map) when map_size(map) == 0 do
%{}
end
def modify(map) when map_size(map) == 1 do
#something else
end
def modify(map) do
# expensive operation
%{ modified: "map" }
end
end
Aquí hay una salida de iex usando Kernel.match?/2
para mostrar map_size/1
en acción:
iex(6)> Kernel.match?(map when map_size(map) == 1, %{})
false
iex(7)> Kernel.match?(map when map_size(map) == 1, %{foo: "bar"})
true
Además de todas las respuestas geniales proporcionadas hasta ahora, también puede considerar el uso del operador de pin único que parece un sombrero o un punto de flecha superior. Lo usa para prefijar una variable con él para asegurar que coincida con su valor, como se indica en la documentación relevante:
Utilice el operador pin ^ cuando desee que el patrón coincida con el valor de una variable existente en lugar de volver a enlazar la variable
A continuación se muestra un ejemplo:
defmodule A do
def determine_map_volume(some_map) do
an_empty_map = %{}
some_map
|> case do
^an_empty_map -> :empty # Application of pin operator
_ -> :not_empty
end
end
end
Que se puede verificar de la siguiente manera:
A.determine_map_volume(%{})
:empty
A.determine_map_volume(%{a: 1})
:not_empty
El método que pretenda utilizar depende de su preferencia personal / organizacional para la legibilidad de su código.
Funciona de esta forma por diseño, pero admite que puede ser un poco confuso a primera vista. Esta característica le permite desestructurar mapas usando la coincidencia de patrones, sin tener que especificar todas las claves. Por ejemplo:
iex> %{b: value} = %{a: 1, b: 2, c: 3}
%{a: 1, b: 2, c: 3}
iex> value
2
En consecuencia, %{}
coincidirá con cualquier mapa. Si desea hacer coincidir un mapa vacío en una función, debe usar una cláusula de guardia:
defmodule PatternMatch do
def modify(map) when map == %{} do
%{}
end
def modify(map) do
# ...
end
end