Подтвердить что ты не робот

Функция совпадения шаблонов с пустой картой

Я играю с совпадением с шаблоном, и я узнал, что не совсем легко сопоставить параметры сопоставления метода с пустой картой. Я думал, что это будет примерно так:

defmodule PatternMatch do
  def modify(%{}) do
    %{}
  end

  def modify(map) do
    # expensive operation
    %{ modified: "map" }
  end
end

Но похоже, что первое предложение функции соответствует произвольным картам:

iex> PatternMatch.modify(%{a: "map"})
==> %{}

Есть ли другой способ проверить пустые карты?

4b9b3361

Ответ 1

Он работает таким образом по дизайну, но, по общему признанию, на первый взгляд может быть немного запутанным. Эта функция позволяет вам деструктурировать карты, используя сопоставление шаблонов, не указывая всех ключей. Например:

iex> %{b: value} = %{a: 1, b: 2, c: 3}
%{a: 1, b: 2, c: 3}

iex> value
2

Следовательно, %{} будет соответствовать любой карте. Если вы хотите сопоставить пустую карту в функции, вы должны использовать предложение охраны:

defmodule PatternMatch do
  def modify(map) when map == %{} do
    %{}
  end

  def modify(map) do
    # ...
  end
end

Ответ 2

В дополнение к ответу @PatrickOscity (который я буду использовать для пустой карты) вы можете использовать map_size/1 охрану для сопоставления с картами с рядом клавиши:

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

Вот результат iex, используя Kernel.match?/2, чтобы показать map_size/1 в действии:

iex(6)> Kernel.match?(map when map_size(map) == 1, %{})
false
iex(7)> Kernel.match?(map when map_size(map) == 1, %{foo: "bar"})
true