When using the pipe operator in Elixir, is it possible to be selective/specific about the output that is passed from the first function to the second?
For example, I'm processing a map in three steps - I need to drop two keys, update the value of a different key, and finally pop another key, whose value I need to use later on in my code. Here's an illustration of what I'd ideally be able to achieve:
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
So that'd drop the :__struct__ and :__meta__ keys, update the value of the :id key by replacing the word "join" with "scope", and then pop the :user_id key off, leaving me with {scope, record}, where scope is the value of the popped key and record is the modified map. The code, as is, does not work, of course.
Here's a piece of sample data:
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"},
]
The first step in this process works, because drop/2 returns just the modified map, which is the correct input for the first parameter to get_and_update/3. However, get_and_update/3 returns a tuple where the first value is the value that that the function replaced and the second value is the modified map. This is where the pipe chain fails, because pop/2 expects a map as the first argument, and here it's receiving a tuple.
Is there a way that I can control the output of get_and_update/3 so that only the second value from the returned tuple is passed through the pipe to pop/2? I've been able to get the output that I need by breaking this chain up into several pieces, but if it were at all possible to chain these together, I'd like to.
|> elem(1)before|> Map.pop(...)? There's alsoMap.updateif you don't care about the old value inMap.get_and_update.elem()- didn't know about that. I'll probably end up going withupdate(), butelem()technically answers my question.