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.update
if you don't care about the old value inMap.get_and_update
. – Dogbertelem()
- didn't know about that. I'll probably end up going withupdate()
, butelem()
technically answers my question. – skwidbreth