有没有一种简单的方法来||在万灵药中无模式匹配?
我有一个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”为PARAMS。
请注意,我可以将它设置为一个变量,它会导致零,如果我访问它,它不存在:
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)
然后让deсide我们想要与此有关。我们想要处理群组吗?让我们这样做:
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)
这看起来像你需要什么?
我打算接受这个答案,因为我要求的是不可能的,这提供了一些关于酏剂如何工作的有用信息 –
模式匹配_will_失败的关键。您可以将'%{“a”=> nil,“b”=> nil,“c”=> nil}'与Enum.group_by的结果合并,但这可能比您提到的替代方案更糟。你也可以创建一个类似于'Map.take'的函数,它返回给定键的值,如果键不存在则返回'nil',并使用它:'[a,b,c] = my_take(Enum。 group_by(...),[“a”,“b”,“c”])''。 – Dogbert
你所要求的东西是不被支持的,但是如果你稍微扩展你的问题(你想要怎么处理这些数据?你为什么要返回'nil'?输入列表是什么样的? )你可以得到一些更广泛的建议。 –