有一种简单的方法||精灵中的零模式匹配



我有一个enum,我正在使用group_by与。

Enum.group_by(my_list, fn x -> x.param end)

结果是它按param值分组。我想快速进行模式匹配,所以我有:

%{"a" => a, "b" => b, "c" => c } = Enum.group_by(my_list, fn x -> x.param end)

但是,当列表丢失" A"," B"或" C"作为参数时,这会陷入问题。

请注意,我可以将其设置为一个变量,如果我访问并且它不存在,它将导致零:

grouped = Enum.group_by(my_list, fn x -> x.param end)
grouped["a"] # this will show as nil or the result if it exists

但是,对于可读性,我只想进行模式匹配并使用变量。这是elixir中不支持的东西吗?

模式匹配是用于自我检查的自信代码,而不仅仅是快速获得值。您的代码检查地图中是否有所有指定的密钥。如果您不需要这样的检查,请不要使用模式匹配。

例如,让我们首先将结果分配给一个变量(实际上在elixir中不变)。

groups = Enum.group_by(my_list, fn x -> x.param end)

然后,让我们消除我们想对此做些什么。我们要处理小组吗?让我们来做:

Enum.map(groups, fn({name, list}) -> process_group(name, list) end)

我们需要处理缺失的组吗?没问题:

missing_groups = Enum.filter(["a", "b", "c"], &(!Map.has_key?(groups, &1)))
Enum.map(missing_groups, fn(name) -> process_missing_group(name) end)

想通过钥匙过滤?这也不是问题:

# First variant:
filtered_groups = Enum.into(Enum.filter(groups, fn({k, v}) -> k in ["a", "b", "c"] end), %{})
# Second variant: 
filtered_groups = Map.drop(groups, ["d", "e", "f", "g", "h"]) 

您真的想添加缺少的键吗?好的,如果是这样,请让我们这样做:

all_groups = Enum.into(["a", "b", "c"], %{}, &({&1, Map.get(groups, &1)}))
process_all_groups(all_groups)

您可以看到,任何此操作的模式匹配实际上都不需要。实际上,您根本不需要变量,它们只是为了可读性。

现在您可以说"好,好,但是我想为不同的组做不同的操作"。在这里,您也可以在这里使用图案匹配功能。

def process_group(name, nil), do: action_empty(name)
def process_group("a", list), do: action_a(list)
def process_group("b", list), do: action_b(list)
def process_group(name, [x]), do: single_lement_action(name, x)
def process_group(name, list), do: another_action(name, list)

这看起来像您需要的吗?

最新更新