solo regulares regular probar numeros letras expresiones expresion especiales espacios espacio ejemplos caracteres blanco alfanumerico pattern-matching elixir

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