【问题标题】:Is there an easy way to || nil pattern match in elixir?有没有简单的方法||长生不老药中的零模式匹配?
【发布时间】:2017-01-01 20:49:33
【问题描述】:

我有一个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”作为参数时,这会遇到问题。

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

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 不支持的东西吗?

【问题讨论】:

  • 模式匹配因缺少键而失败。您可以将%{"a" => nil, "b" => nil, "c" => nil}Enum.group_by 的结果合并,但这可能比您提到的替代方案更糟糕。您还可以创建一个类似于Map.take 的函数,它返回给定键处的值,如果键不存在则返回nil,并像这样使用它:[a, b, c] = my_take(Enum.group_by(...), ["a", "b", "c"])
  • 您要求的东西不受支持,但也许如果您稍微扩展您的问题(您想对数据做什么?为什么要让nils 回来?输入列表是什么样的?)您可以获得一些更广泛的建议。

标签: elixir


【解决方案1】:

模式匹配是为了自我检查断言代码,而不仅仅是为了快速获取值。您的代码检查地图中是否有所有指定的键。如果您不需要这样的检查,请不要使用模式匹配。

例如,让我们首先将结果分配给一个变量(实际上在 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)

如您所见,任何此操作都不需要 map 的模式匹配。实际上,您根本不需要变量,它们只是为了便于阅读。

现在你可以说“好的,好的,但是我想为不同的组做不同的操作”。如果需要,您还可以在这里使用模式匹配功能。

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)

这看起来像您需要的吗?

【讨论】:

  • 我会接受这个作为答案,因为我所要求的是不可能的,这提供了一些关于 elixir 如何工作的有用信息
猜你喜欢
  • 1970-01-01
  • 2018-11-24
  • 2014-03-16
  • 2015-12-14
  • 2016-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-16
相关资源
最近更新 更多