Elixir 使用管道运算符时获取第一个参数
管道操作员是一件很好的事情。 例如,我希望在Elixir 使用管道运算符时获取第一个参数,elixir,Elixir,管道操作员是一件很好的事情。 例如,我希望在Enum.reduce中使用enumerable,或者其他什么: foo |> bar(...) |> Enum.reduce([], fn x, acc -> acc ++ [Enum.at(<enumerable>, x)] end) 当在匿名函数中使用管道运算符以及&1时,第一个参数可能存在语法糖?最好只移动整个枚举。将减少到它自己的函数,该函数接受一个参数并命名,这样每个人都能理解它在做什么重新排列不是最具描述性
Enum.reduce
中使用enumerable,或者其他什么:
foo |> bar(...) |> Enum.reduce([], fn x, acc -> acc ++ [Enum.at(<enumerable>, x)] end)
当在匿名函数中使用管道运算符以及
&1
时,第一个参数可能存在语法糖?最好只移动整个枚举。将减少到它自己的函数,该函数接受一个参数并命名,这样每个人都能理解它在做什么<代码>重新排列
不是最具描述性的名称,但我不确定此过程在您的应用程序中是如何使用的
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]
真是个坏主意,因为它每次都会从头开始在内存中重新创建列表。它是O(n)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),这是它执行操作的合理时间。我认为在第二个示例中,您忘记了将枚举作为Enum.reduce
的第一个参数。即使如此,我仍然不清楚它应该做什么。您有类似于[3,1,2]
的内容,并希望将其转换为[2,3,1]
?是的,我忘记了第一个参数。编辑后的问题。我想知道,长生不老药在列表中并没有通常的插入操作。因此,我使用的是++运算符,我认为它比[thing | list]
更清晰,反之亦然。结果很慢。。。不管怎样,谢谢!Elixir中的列表是内部单独链接的列表。它有它的局限性,但在不变性方面非常有效。例如,当您有long_list
并预先编写不同的内容时:[a | long_list]
和[b | long_list]
在内部它指向相同的long_list
,因为它无法更改。如果您可以使用[long\u list]+[element]
修改列表,则会破坏此优化。当然,缺点是追加速度慢O(n),需要复制整个长列表才能追加一个元素。
def rearrange(enumerable) do
enumerable
|> Enum.reduce([], fn x, acc -> [Enum.at(enumerable, x) | acc] end)
|> Enum.reverse
end