是否可以选择将管道输出插入Elixir函数args的位置?

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)

Gaz*_*ler 6

您只需绑定到变量即可捕获第一个结果,然后在第二个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)

我发现使用变量更具可读性,但是该选项在那里。

  • 或者,您可以只创建一个私有函数,以适当的顺序接收参数,然后执行调用。:) (2认同)