【问题标题】:Elixir: Capturing the rest of a map using pattern matchingElixir:使用模式匹配捕获地图的其余部分
【发布时间】:2017-11-30 02:03:08
【问题描述】:

我想同时匹配地图中的特定键,捕获该地图的其余部分。我希望这样的事情会起作用:

iex(10)> %{"nodeType" => type | rest} = %{"nodeType" => "conditional", "foo" => "bar"}

** (CompileError) iex:10: cannot invoke remote function IEx.Helpers.|/2 inside match

我们的目标是编写一组函数,它们接受一个地图,在地图的一个字段上进行模式匹配,并对地图的其余部分执行一些转换。

def handle_condition(%{"nodeType" => "condition" | rest}) do
  # do something with rest
done
def handle_expression(%{"nodeType" => "expression" | rest}) do
  # do something with rest
done

但看起来我需要被调用者单独传递 nodeType,除非我遗漏了什么。

【问题讨论】:

  • 我想要这种语法。我正要问同样的问题,却猜到了完全相同的语法def update_document(%{id: id, revision: revision | rest}) do # couchdb stuff here end
  • 一般注意,nodeType 字段表示使用struct 可能会比仅仅使用地图更好。请参阅elixir-lang.github.io/getting-started/structs.html 在不知道您的确切用例的情况下,我无法确定,但所描述的用法对我来说是一种代码味道,您没有使用可用的最佳工具。

标签: pattern-matching elixir


【解决方案1】:

您可以轻松捕获整个地图 - 或许这就足够了?

def handle_condition(all = %{"nodeType" => "condition"}) do
  # do something with all
end

或者:

def handle_condition(all = %{"nodeType" => "condition"}) do
  all = Map.delete(all, "nodeType")
  # do something with all
end

【讨论】:

  • 很遗憾%{"nodeType" => "condition" | rest}不起作用,就像JS中的扩展运算符:{nodeType: 'condition', ...rest}
【解决方案2】:

实现此目的的另一个好方法是使用Map.pop/2

def handle(%{} = map), do: handle(Map.pop(map, "nodeType"))

def handle({"condition", rest}) do
  # ... handle conditions here
end

def handle({"expression", rest}) do
  # ... handle expressions here
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 2013-06-10
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多