【问题标题】:Elixir - pass partial output through pipe operatorElixir - 通过管道运算符传递部分输出
【发布时间】:2018-04-01 15:43:29
【问题描述】:

在 Elixir 中使用管道运算符时,是否可以选择性地/特定于从第一个函数传递到第二个函数的输出?

例如,我分三个步骤处理地图 - 我需要删除两个键,更新另一个键的值,最后弹出另一个键,我需要稍后在我的代码中使用它的值。这是我理想情况下能够实现的示例:

for r <- records do
  {scope, record} = 
    Map.drop(r, [:__struct__, :__meta__])
    |> Map.get_and_update(:id, fn current_value -> 
      {current_value, String.replace(current_value, "join", "scope", global: false)}
    end)
    |> Map.pop(:user_id)

  # SOME OTHER STUFF...

end

这样会删除 :__struct__:__meta__ 键,通过将单词“join”替换为“范围”来更新 :id 键的值,然后关闭 :user_id 键,离开我用{scope, record},其中scope 是弹出键的值,record 是修改后的映射。当然,按原样编写的代码是行不通的。

这是一段示例数据:

records = [
  %{__struct__: "foo", __meta__: "bar", id: "resource_join:1234", user_id: "user:1234"},
  %{__struct__: "foo", __meta__: "bar", id: "resources_join:5678", user_id: "user:5678"},
]

此过程的第一步有效,因为drop/2 只返回修改后的映射,这是get_and_update/3 第一个参数的正确输入。但是,get_and_update/3 返回一个元组,其中第一个值是函数替换的值,第二个值是修改后的映射。这是管道链失败的地方,因为pop/2 需要一个映射作为第一个参数,而这里它正在接收一个元组。

有没有一种方法可以控制get_and_update/3 的输出,以便只有返回元组中的第二个值通过管道传递到pop/2?通过将这条链分成几部分,我已经能够获得我需要的输出,但如果有可能将它们链接在一起,我愿意。

【问题讨论】:

  • 考虑包含数据示例,这样任何人都可以在控制台中运行您的代码
  • 您是否考虑过将with 与您所拥有的内容结合使用?
  • 你的意思是想在|&gt; Map.pop(...)之前加上|&gt; elem(1)?如果您不关心 Map.get_and_update 中的旧值,还有 Map.update
  • @Dogbert 正确,感谢您指出elem() - 不知道。我可能最终会选择update(),但elem() 在技术上回答了我的问题。
  • @denis.peplin - 好电话,我添加了一段示例数据。

标签: elixir


【解决方案1】:

由于您想丢弃元组的第一个元素,只将第二个元素传递给Map.pop,您可以将|&gt; elem(1) 添加到管道中:

|> Map.get_and_update(:id, fn current_value -> 
  {current_value, String.replace(current_value, "join", "scope", global: false)}
end)
|> elem(1)
|> Map.pop(:user_id)

另外,Map.get_and_update + elem(1) 可以只替换为 Map.update,它不会返回键的旧值:

|> Map.update(fn current_value -> 
  String.replace(current_value, "join", "scope", global: false)
end)
|> Map.pop(:user_id)

【讨论】:

    猜你喜欢
    • 2017-06-23
    • 2017-04-21
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 2017-05-25
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    相关资源
    最近更新 更多