Is it possible to choose where the pipe output is inserted into the arguments of the Elixir function?

Consider the (smelly, non-idiomatic) function, as shown below:

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 

This function will accept a list of lists, a list of two indices, and a value to be inserted into the list of lists at the location indicated by the indices.

As a first step to making this bigger than Elixir-ey, I'm starting to lay the pipe:

 array |> Enum.at(second_coord) |> List.update_at(first_coord, fn(x) -> val end) 

I like it most, but how can I pass this output to the anonymous function of the last call to List.update_at ? . I can put it in the original call, but it seems like a failure:

 List.update_at(array, second_coord, fn(y) -> array |> Enum.at(second_coord) |> List.update_at(first_coord, fn(x) -> val end) end) 
+4
source share
1 answer

You can simply bind a variable to record your first result, and then replace it in the second call to List.update_at/3

 def update_2d(array, inds, val) do [first_coord, second_coord] = inds 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 

You can also use the capture statement:

  def update_2d(array, inds, val) do [first_coord, second_coord] = inds array |> Enum.at(second_coord) |> List.update_at(first_coord, fn(x) -> val end) |> (&(List.update_at(array, second_coord, fn(y) -> &1 end))).() end 

I find the use of the variable more readable, but there is an option.

+4
source

All Articles