下面是我想完成的任务。
> a = ["a","b","c","d","e"]
> Enum.reject_multiple(a,[1,3])
["a", "c", "e"]
我能想到的最清晰的方法是包含索引,拒绝所需的项目。
rejected_indices = MapSet.new([1, 3])
["a", "b", "c", "d", "e"]
|> Stream.with_index()
|> Stream.reject(fn {_item, index} -> index in rejected_indices end)
|> Enum.map(&elem(&1, 0))
#=> ["a", "c", "e"]
虽然正确的方法肯定是由 @BrettBeatty 提供的,但我想贴出一个例子,说明如何使用一些元编程魔法,通过一次通过列表来实现。只是为了举例说明。
defmodule MyEnum do
defmacro decimate(list, indices) do
quote do
unquote(list)
|> Enum.reduce({0, []}, fn
_, {i, acc} when i in unquote(indices) -> {i + 1, acc}
e, {i, acc} -> {i + 1, [e | acc]}
end)
|> elem(1)
|> Enum.reverse()
end
end
end
require MyEnum
MyEnum.decimate(~w[a b c d e], [1, 3])
#⇒ ["a", "c", "e"]
宏是需要一个能力,把 indices
在守卫。