管道操作员是非常好的事情。
例如,我希望将枚举用于Enum.reduce
或其他东西:
foo |> bar(...) |> Enum.reduce([], fn x, acc -> acc ++ [Enum.at(<enumerable>, x)] end)
然后我被迫写道:
enumerable = foo |> bar(...)
Enum.reduce(enumerable, [], fn x, acc -> acc ++ [Enum.at(enumerable, x)] end)
在匿名函数中使用管道运算符和&1
时,第一个参数可能存在语法糖吗?
答案 0 :(得分:3)
简单地将整个Enum.reduce
移动到它自己的函数是一个好主意,该函数接受一个参数并命名它,这样每个人都可以理解它在做什么。 rearrange
不是最具描述性的名称,但我不确定您的应用中如何使用此过程。
def rearrange(enumerable) do
Enum.reduce(enumerable, [], fn x, acc -> acc ++ [Enum.at(enumerable, x)] end)
end
foo |> bar(...) |> rearrange
另一种解决方案是使用您在问题中提到的匿名函数。情况更糟,但我提到它是完整的。
&(Enum.reduce(&1, [], fn x, acc -> acc ++ [Enum.at(&1, x)] end))
这看起来真的很复杂。您在匿名函数中有匿名函数,但它显示您可以在函数中多次使用&1
。
最后,acc ++ [thing]
非常糟糕,因为它每次都会从头开始重新创建内存中的列表。它开着)。 Enum.at
也是线性的,Enum.reduce
也是线性的,所以这个函数是O(n ^ 3)。
您可以改为fn x, acc -> [Enum.at(enumerable, x) | acc] end
并在结尾处反转结果。
def rearrange(enumerable) do
enumerable
|> Enum.reduce([], fn x, acc -> [Enum.at(enumerable, x) | acc] end)
|> Enum.reverse
end
[thing | acc]
是O(1)。这将使整个过程O(n ^ 2),这是它正在做的事情的合理时间。