bri*_*tar 5 functional-programming pipeline list elixir
考虑一个如下所示的(有臭味的,非惯用的)功能:
def update_2d(array, inds, val) do
[first_coord, second_coord] = inds
new_arr = List.update_at(array, second_coord, fn(y) ->
List.update_at(Enum.at(array, second_coord),
first_coord, fn(x) -> val end) end)
end
Run Code Online (Sandbox Code Playgroud)
此函数将接收列表列表,两个索引列表以及在列表列表中由索引指定的位置插入的值。
作为使这种Elixir-ey的第一步,我开始铺设管道:
array
|> Enum.at(second_coord)
|> List.update_at(first_coord, fn(x) -> val end)
Run Code Online (Sandbox Code Playgroud)
这使我获得了大部分帮助,但是如何将输出输出到上次List.update_at
调用的匿名函数中呢?我可以将其嵌套在原始调用中,但这似乎是放弃的:
List.update_at(array, second_coord, fn(y) ->
array
|> Enum.at(second_coord)
|> List.update_at(first_coord, fn(x) -> val end)
end)
Run Code Online (Sandbox Code Playgroud)
您只需绑定到变量即可捕获第一个结果,然后在第二个List.update_at/3
调用中将其替换
def update_2d(array, inds = [first_coord, second_coord], val) do
updated =
array
|> Enum.at(second_coord)
|> List.update_at(first_coord, fn(x) -> val end)
List.update_at(array, second_coord, fn(x) -> updated end)
end
Run Code Online (Sandbox Code Playgroud)
您还可以使用捕获运算符执行此操作:
def update_2d(array, inds = [first_coord, second_coord], val), do:
array
|> Enum.at(second_coord)
|> List.update_at(first_coord, fn(x) -> val end)
|> (&(List.update_at(array, second_coord, fn(y) -> &1 end))).()
Run Code Online (Sandbox Code Playgroud)
我发现使用变量更具可读性,但是该选项在那里。