Reputation: 887
Pipe operator is very nice thing.
For example, I wish to use enumerable into Enum.reduce
or something yet:
foo |> bar(...) |> Enum.reduce([], fn x, acc -> acc ++ [Enum.at(<enumerable>, x)] end)
Then I am compelled to write:
enumerable = foo |> bar(...)
Enum.reduce(enumerable, [], fn x, acc -> acc ++ [Enum.at(enumerable, x)] end)
May be exist syntax sugar for the first argument when used pipe operator as well as &1
in anonymous function?
Upvotes: 2
Views: 2787
Reputation: 9289
It would be a good idea to simply move the whole Enum.reduce
to its own function that takes one argument and name it, so everyone can understand what is it doing. rearrange
is not the most descriptive name, but I am not sure how is this procedure used in your app.
def rearrange(enumerable) do
Enum.reduce(enumerable, [], fn x, acc -> acc ++ [Enum.at(enumerable, x)] end)
end
foo |> bar(...) |> rearrange
Another solution would be to use anonymous function as you mentioned in your question. It is worse, but I mention it for completeness.
&(Enum.reduce(&1, [], fn x, acc -> acc ++ [Enum.at(&1, x)] end))
This looks really convoluted. You have anonymous function inside anonymous function, but it shows, that you can use &1
more than one time in your function.
Lastly, acc ++ [thing]
is really bad idea, because it recreates the list in memory from scratch every time. It is O(n). Enum.at
is also linear and so is Enum.reduce
, so this function is O(n^3).
You can do fn x, acc -> [Enum.at(enumerable, x) | acc] end
instead and reverse the result at the end.
def rearrange(enumerable) do
enumerable
|> Enum.reduce([], fn x, acc -> [Enum.at(enumerable, x) | acc] end)
|> Enum.reverse
end
[thing | acc]
is O(1). This will make the whole procedure O(n^2) and that is reasonable time for what it is doing.
Upvotes: 3