2017-10-20 49 views
1

在Elixir中使用管道運算符時,是否可以對從第一個函數傳遞到第二個函數的輸出進行選擇性/特定處理?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__鍵,用「範圍」一詞替換「加入」更新: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?我已經能夠通過將這個鏈條分成幾個部分來獲得我需要的輸出,但是如果可以將這些鏈接在一起,我想。

+0

考慮包括數據例子,所以任何人都可以在控制檯 –

+0

運行代碼,你看着使用[有](HTTP:// learningelixi r.joekain.com/learning-elixir-with/)結合你在那裏? – matov

+0

你的意思是在'|> Map.pop(...)''之前加入'|> elem(1)'嗎?如果您不關心Map.get_and_update中的舊值,那麼還有'Map.update'。 – Dogbert

回答

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)