如果我收到下面这样的信任重构机会警告,该怎么办?
One `Enum.reject/2` is more efficient than `Enum.reject/2 |> Enum.reject/2`
例如,如何使用oneEnum.reject/2
而不是Enum.reject/2 |> Enum.reject/2
重新编码以下函数?
def my_reject_test() do
(1..10)
|> Enum.reject(&(rem(&1, 2) == 0))
|> Enum.reject(&(rem(&1, 3) == 0))
end
您可以使用or/2
组合条件:
iex> Enum.reject(1..10, &(rem(&1, 2) == 0 or rem(&1, 3) == 0))
[1, 5, 7]
credo之所以指出这一点,是因为管道两个Enum.reject/2
将首先生成一个中间列表,然后再次遍历它:
iex> 1..10
1..10
iex> |> Enum.reject(&(rem(&1, 2) == 0))
[1, 3, 5, 7, 9]
iex> |> Enum.reject(&(rem(&1, 3) == 0))
[1, 5, 7]
一个简单的方法是:
(1..10)
|> Enum.reject(fn x -> rem(x, 2) == 0 || rem(x, 3) == 0 end)
|> IO.inspect()
对于更复杂的场景,我有时会使用Enum.reduce/3
,或者考虑添加一个命名的私有函数来执行逻辑(为了可读性(。
这是一个很好的提醒,遍历列表可能会很昂贵(对于长列表(,所以只要可能,您应该尽量减少遍历列表的次数。使用两次Enum.reject/2
使算法的复杂度为O(2n(,而仅使用一次使算法的复杂性为O(n(。