当前位置: 首页 > 文档资料 > Elixir 中文教程 >

Enumerables( Enumerables)

优质
小牛编辑
143浏览
2023-12-01

可枚举是可以枚举的对象。 “枚举”是指逐个计算集合/集合/类别的成员(通常按顺序,通常按名称)。

Elixir提供了enumerables和Enum模块的概念来使用它们。 正如名称所述,Enum模块中的函数仅限于枚举数据结构中的值。 可枚举数据结构的示例是列表,元组,映射等.Enum模块为我们提供了100多个处理枚举的函数。 我们将在本章中讨论一些重要的功能。

all?

当我们all使用? 函数,整个集合必须评估为true否则将返回false。 例如,要检查列表中的所有元素是否都是奇数,那么。

res = Enum.all?([1, 2, 3, 4], fn(s) -> rem(s,2) == 1 end) 
IO.puts(res)

运行上述程序时,会产生以下结果 -

false

这是因为并非此列表的所有元素都是奇数。

any?

顾名思义,如果集合的任何元素的计算结果为true,则此函数返回true。 例如 -

res = Enum.any?([1, 2, 3, 4], fn(s) -> rem(s,2) == 1 end)
IO.puts(res)

运行上述程序时,会产生以下结果 -

true

chunk

此函数将我们的集合划分为作为第二个参数提供的大小的小块。 例如 -

res = Enum.chunk([1, 2, 3, 4, 5, 6], 2)
IO.puts(res)

运行上述程序时,会产生以下结果 -

[[1, 2], [3, 4], [5, 6]]

each

可能有必要迭代一个集合而不产生新值,对于这种情况我们使用each函数 -

Enum.each(["Hello", "Every", "one"], fn(s) -> IO.puts(s) end)

运行上述程序时,会产生以下结果 -

Hello
Every
one

map

要将我们的函数应用于每个项目并生成一个新集合,我们使用map函数。 它是函数式编程中最有用的结构之一,因为它非常富有表现力和简洁性。 让我们考虑一个例子来理解这一点。 我们将存储在列表中的值加倍并将其存储在新的列表中 -

res = Enum.map([2, 5, 3, 6], fn(a) -> a*2 end)
IO.puts(res)

运行上述程序时,会产生以下结果 -

[4, 10, 6, 12]

reduce

reduce函数帮助我们将可枚举减少到单个值。 为此,我们提供一个可选的累加器(在本例中为5)以传递给我们的函数; 如果没有提供累加器,则使用第一个值 -

res = Enum.reduce([1, 2, 3, 4], 5, fn(x, accum) -> x + accum end)
IO.puts(res)

运行上述程序时,会产生以下结果 -

15

累加器是传递给fn的初始值。 从第二次调用开始,前一次调用返回的值将作为accum传递。 我们也可以使用reduce而不用累加器 -

res = Enum.reduce([1, 2, 3, 4], fn(x, accum) -> x + accum end)
IO.puts(res)

运行上述程序时,会产生以下结果 -

10

uniq

uniq函数从我们的集合中删除重复项,并仅返回集合中的元素集。 例如 -

res = Enum.uniq([1, 2, 2, 3, 3, 3, 4, 4, 4, 4])
IO.puts(res)

在程序上运行时,会产生以下结果 -

[1, 2, 3, 4]

急切的评价

Enum模块中的所有功能都非常渴望。 许多函数都期望枚举并返回一个列表。 这意味着当使用Enum执行多个操作时,每个操作都将生成一个中间列表,直到我们到达结果。 让我们考虑以下示例来理解这一点 -

odd? = &(odd? = &(rem(&1, 2) != 0) 
res = 1..100_000 |> Enum.map(&(&1 * 3)) |> Enum.filter(odd?) |> Enum.sum 
IO.puts(res) 

运行上述程序时,会产生以下结果 -

7500000000

上面的例子有一个操作流程。 我们从一个范围开始,然后将范围中的每个元素乘以3.第一个操作现在将创建并返回一个包含100_000个项目的列表。 然后我们保留列表中的所有奇数元素,生成一个新列表,现在有50_000个项目,然后我们对所有条目求和。

上面代码片段中使用的符号是pipe operator :它只是从左侧的表达式获取输出,并将其作为第一个参数传递给右侧的函数调用。 它类似于Unix | 运算符。 其目的是突出由一系列功能转换的数据流。

没有pipe运算符,代码看起来很复杂 -

Enum.sum(Enum.filter(Enum.map(1..100_000, &(&1 * 3)), odd?))

我们还有许多其他功能,但这里只描述了一些重要的功能。