Enum 模块

一些枚举集合元素的算法。

Enum

Enum 模块提供了超过一百个函数,和我们上节课提到的集合交互。

这篇课程只会讲其中的一部分,要想了解全部的函数,请访问官方的 Enum 文档。
而要想了解懒枚举(lazy enumeration),访问 Stream 模块。

all?

使用 all? 的时候,我们要提供一个函数来作用到要操作的集合上。只有当函数在所有的元素上都返回 true 的时候,all? 才会返回 true,否则结果就是 false

iex> Enum.all?(["foo", "bar", "hello"], fn(s) -> String.length(s) == 3 end)  
false  
iex> Enum.all?(["foo", "bar", "hello"], fn(s) -> String.length(s) > 1 end)  
true  

any?

和上面不同,只要有一个元素被函数调用返回 trueany? 就会返回 true

iex> Enum.any?(["foo", "bar", "hello"], fn(s) -> String.length(s) == 5 end)  
true  

chunk

如果你想把你的集合拆分成小的分组,chunk 就是你要找的函数:

iex> Enum.chunk([1, 2, 3, 4, 5, 6], 2)  
[[1, 2], [3, 4], [5, 6]]  

chunk 还有其他选项,在这里不深入介绍。如果感兴趣,前往 chunk/2 的官方文档去了解。

chunk_by

如果不按照数量分组(每组的元素数量相同),我们可以使用 chunk_by 方法:

iex> Enum.chunk_by(["one", "two", "three", "four", "five"], fn(x) -> String.length(x) end)  
[["one", "two"], ["three"], ["four", "five"]]  

each

有时候需要遍历某个集合进行操作,但是不想产生新的值(不把函数的遍历调用结果返回),这种情况下,可以使用 each

iex> Enum.each(["one", "two", "three"], fn(s) -> IO.puts(s) end)  
one  
two  
three  

注意each 函数会返回原子 :ok

map

要把某个元素都执行某个函数,并且把结果作为新的集合返回,要使用 map 函数:

iex> Enum.map([0, 1, 2, 3], fn(x) -> x - 1 end)  
[-1, 0, 1, 2]  

min

在集合中找到最小的值:

iex> Enum.min([5, 3, 0, -1])  
-1

max

返回集合中最大的值:

iex> Enum.max([5, 3, 0, -1])  
5  

reduce

使用 reduce,我们可以把集合不断计算,最终得到一个值。我们需要提供一个可选的累加值(在这个例子中是 10),如果没有累加值,集合中的第一个值会被使用。

iex> Enum.reduce([1, 2, 3], 10, fn(x, acc) -> x + acc end)  
16  
iex> Enum.reduce([1, 2, 3], fn(x, acc) -> x + acc end)  
6