在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”替换为“scope”来更新:id
键的值,然后弹出{ {1}}关闭,留下: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
?我已经能够通过将这个链条分成几个部分来获得我需要的输出,但是如果它们完全可以将这些链接在一起,我愿意。
答案 0 :(得分:1)
由于您要丢弃元组的第一个元素并仅将第二个元素传递给Map.pop
,因此您可以将|> 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)