是否相当于Ruby Enumerable#one?枚举#没有?在Elixir?

时间:2018-02-02 09:54:12

标签: enums elixir

如何以有效的方式在Elixir中实施one?none?

您如何看待这个?

defmodule MyEnum do
  def one?(enum, fun) do
    Enum.count(enum, fun) == 1 && true || false
  end

  def none?(enum, fun) do
    Enum.count(enum, fun) == 0 && true || false
  end
end

用法示例:

iex(6)> MyEnum.none?([0,0,0,0], fn(x) -> x == 1 end)
true
iex(7)> MyEnum.none?([0,0,1,0], fn(x) -> x == 1 end)
false
iex(8)> MyEnum.none?([0,1,1,0], fn(x) -> x == 1 end)
false
iex(9)> MyEnum.one?([0,1,1,0], fn(x) -> x == 1 end)
false
iex(10)> MyEnum.one?([0,1,0,0], fn(x) -> x == 1 end)
true
iex(11)> MyEnum.one?([0,0,0,0], fn(x) -> x == 1 end)
false

2 个答案:

答案 0 :(得分:6)

我会使用Stream.filterEnum.take(2)来实施one?。这将确保在您的fun解决方案将遍历整个枚举时,只会遍历最多2个匹配Enum.count的元素。

对于none?,您只需返回!Enum.any?(...)

defmodule MyEnum do
  def one?(enum, fun) do
    case enum |> Stream.filter(fun) |> Enum.take(2) do
      [_] -> true
      _ -> false
    end
  end

  def none?(enum, fun) do
    !Enum.any?(enum, fun)
  end
end

IO.inspect MyEnum.none?([0,0,0,0], fn(x) -> x == 1 end)
IO.inspect MyEnum.none?([0,0,1,0], fn(x) -> x == 1 end)
IO.inspect MyEnum.none?([0,1,1,0], fn(x) -> x == 1 end)
IO.inspect MyEnum.one?([0,1,1,0], fn(x) -> x == 1 end)
IO.inspect MyEnum.one?([0,1,0,0], fn(x) -> x == 1 end)
IO.inspect MyEnum.one?([0,0,0,0], fn(x) -> x == 1 end)

输出:

true
false
false
false
true
false

答案 1 :(得分:2)

Enum模块已经有Enum.all?/2Enum.any?/2,正如Dogbert所说(我把它放在这里作为参考链接。)

此外,对于one?而言,这是一种奇特的方式,其表现肯定比Enum.take(2)差得多,但仍然很有趣(使用理解力):

"*" == for elem <- [0,1,1,0], fn e -> e == 1 end.(elem), into: "", do: "*"