iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 30
0
自我挑戰組

滿滿的紅寶石不拿嗎?-- 去吧!我把世界上的一切都放在那裡了! 系列 第 30

Enumerator <> 一旦上了船,程式就是不會背叛你的夥伴 - 滿滿的紅寶石不拿嗎?

[Day30] 還在等什麼!快來成為 Ruby 工程師啊!(誤)

終於來到鐵人賽的最後一天了!以為我要寫個完賽心得帶過嗎?雖然很想這樣做,不過,這裡並不是停下腳步的地方啊!

這篇要介紹的是 Enumerator


Enumerator 是什麼?

剛開始看到這個詞只覺得陌生 + 困惑

上網查了許久,Enumerator 似乎沒有一個很精準的中文翻譯,但可以找到像是 external, iterator, Enumerable Module 這些關鍵字。

但其實它一直都在我們身邊。

平時 coding 可能就已經看過它,那就是當使用 each 方法操作陣列相關的物件時,又不小心忘了寫 Block 的話:

[1,2,3].each
 => #<Enumerator: [1, 2, 3]:each> 

就會出現這個 Enumerator ! 可是···這是什麼意思?還是不懂。

沒關係把 Enumerator 放一邊,先來看看 Enumerable 能不能輔助我理解。


Enumerable 又是什麼?

雖然和上一個概念相比,似乎只有單字詞性的變化,不過 Enumerable 的概念明確許多。

首先,Enumerable 是一種模組(Module),又可以稱為「列舉」,來瞧瞧 Ruby 官方文件的定義:

列舉提供陣列和雜湊搜尋、排序或轉換集合內元素的功能。而陣列或雜湊必須各自提供一個方法,該方法可以產生集合的連續成員···(?)

簡單來說,像是 each, select, map, match, sort, grep 這些常用的方法都屬於 Enumerable 的範疇。

詳細內容請參考 Ruby-Doc Module: Enumerable


External Iterator

接下來介紹外部迭代器(External Iterator)

大部分時候我們都在做的是 Internal Iterator
像是平常在丟迴圈,或是上在介紹的陣列方法,都屬於 Internal Iterator ,譬如想從一個陣列中選取一些元素:

list = [1, 2, 3, 4]

list.select do |n|
  n > 2
end

#=> [3, 4]

不過,既然有 Internal ,也就有 ExternalInternal Iterator 是由陣列或雜湊這類的集合物件控制,而 External Iterator 則是由外部來控制,像是:

icons = %w[up down].to_enum(:cycle)
list = [1, 2, 3, 4, 5]

list.each do
  puts icons.next
end

# =>
up
down
up
down
up
 => [1, 2, 3, 4, 5] 

在這段程式碼裡,icons 被指定使用 cycle 方式在做迭代,所以當 next 到最後一個元素,下一次的 next 就會從頭再來過。


所以,什麼是 Enumerator?

我這邊引用五倍紅寶石 DC 助教的原話:

Enumerator 最簡單的解釋是 Enumerable 加上 External Iteration,而 EnumeratorEnumerable 的合作方式是前者負責產生、儲存資料,『需要時』再以後者的方法運用。

譬如:

list = [1,2,3].each
#=> #<Enumerator: [1, 2, 3]:each>

list.select { |x| x.odd? }
#=> [1, 3]

除了這種彈性的用法之外,Enumerator 的另一個特性是能把物件不斷串起來,以最近超紅的電影《天能》為例:

'TENET'.split('').reverse_each.with_index(1) do |word, index|
  puts "#{word}"
end
T
E
N
E
T
 => ["T", "E", "N", "E", "T"] 

果然是天能!時光回溯!


結語

Enumerator 的概念不是很好理解,在尋找文獻和研究的過程中不斷撞牆,似乎勉勉強強地看懂了一些,但仍拼湊不出全貌,不過身為工程師,主動接觸一些不熟悉的概念是應該的。

之後的文章應該會放在 Medium 或是自己架的部落格,期許往後的路上還要學得更多,並時常接觸自己不熟悉的領域以及運用所學,天啊!這種既掙扎又興奮的感覺真是太棒了!

那,鐵人賽就先到這邊啦!
在出發的那一刻,我們就已經得到 ONEPIECE 了!


參考來源
與你每天擦身而過的 Enumerator


上一篇
Singleton Class 與物件導向 <> 記錄指針不見了!我們該如何前進到下個島嶼 - 滿滿的紅寶石不拿嗎?
系列文
滿滿的紅寶石不拿嗎?-- 去吧!我把世界上的一切都放在那裡了! 30

1 則留言

0
Ting Ting
iT邦新手 5 級 ‧ 2020-10-08 23:55:32

恭喜完賽!每天期待Andrew的ONE PIECE梗搭配Ruby的日子很有趣XDD

jrnalts iT邦新手 5 級 ‧ 2020-10-08 23:56:51 檢舉

謝謝追蹤XDD
其實每天想要放什麼梗比寫文章的時間還多呢(?)

我要留言

立即登入留言