
- Elixir 教程
- Elixir - 首頁
- Elixir - 概述
- Elixir - 環境
- Elixir - 基本語法
- Elixir - 資料型別
- Elixir - 變數
- Elixir - 運算子
- Elixir - 模式匹配
- Elixir - 決策
- Elixir - 字串
- Elixir - 字元列表
- Elixir - 列表和元組
- Elixir - 關鍵字列表
- Elixir - 對映
- Elixir - 模組
- Elixir - 別名
- Elixir - 函式
- Elixir - 遞迴
- Elixir - 迴圈
- Elixir - 可列舉
- Elixir - 流
- Elixir - 結構體
- Elixir - 協議
- Elixir - 檔案 I/O
- Elixir - 程序
- Elixir - 符號
- Elixir - 推導式
- Elixir - 型別規範
- Elixir - 行為
- Elixir - 錯誤處理
- Elixir - 宏
- Elixir - 庫
- Elixir 有用資源
- Elixir - 快速指南
- Elixir - 有用資源
- Elixir - 討論
Elixir - 可列舉
可列舉物件是可以列舉的物件。“列舉”是指逐一(通常按順序,通常按名稱)計算集合/集合/類別的成員。
Elixir 提供了可列舉的概念以及 Enum 模組 來處理它們。Enum 模組中的函式僅限於(顧名思義)列舉資料結構中的值。可列舉資料結構的示例包括列表、元組、對映等。Enum 模組為我們提供了 100 多個處理列舉的函式。我們將在本章中討論一些重要的函式。
所有這些函式都將可列舉作為第一個元素,將函式作為第二個元素,並在其上進行操作。這些函式描述如下。
all?
我們何時使用all?函式,整個集合必須計算結果為真,否則將返回假。例如,要檢查列表中的所有元素是否都是奇數,則。
res = Enum.all?([1, 2, 3, 4], fn(s) -> rem(s,2) == 1 end) IO.puts(res)
執行上述程式時,會產生以下結果:
false
這是因為此列表並非所有元素都是奇數。
any?
顧名思義,如果集合的任何元素計算結果為真,則此函式返回真。例如:
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中:
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的初始值。從第二次呼叫開始,前一次呼叫的返回值作為累加器傳遞。我們也可以在沒有累加器的情況下使用 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? = &(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 個元素,然後我們對所有條目求和。
上面程式碼片段中使用的|>符號是管道運算子:它只是獲取其左側表示式的輸出,並將其作為第一個引數傳遞給其右側的函式呼叫。它類似於 Unix | 運算子。其目的是突出顯示一系列函式轉換的資料流。
如果沒有管道運算子,程式碼看起來很複雜:
Enum.sum(Enum.filter(Enum.map(1..100_000, &(&1 * 3)), odd?))
我們還有許多其他函式,但是這裡只描述了一些重要的函式。