DAY 5
1

## D-25. 枚舉(enumerate) && Intersection of Two Arrays II

### each, map這兩個方法，做出迭代的行為。

``````2.7.3 :008 > [1, 2, 3].each
=> #<Enumerator: [1, 2, 3]:each>
2.7.3 :009 > {:a => 1, :b => 2, :c => 2}.each
=> #<Enumerator: {:a=>1, :b=>2, :c=>2}:each>
2.7.3 :010 > (1..5).each
=> #<Enumerator: 1..5:each>
2.7.3 :011 > 5.times.each
=> #<Enumerator: 5:times>
2.7.3 :012 > [1, 2, 3].map
=> #<Enumerator: [1, 2, 3]:map>
#map大同小異。
#Enumerator枚舉器。
``````

``````2.7.3 :013 > [1, 2, 3].each {|num| puts num + 1}
2
3
4
=> [1, 2, 3]
2.7.3 :014 > [1, 2, 3].map {|num| num + 1}
=> [2, 3, 4]

#一個一個元素進去操作，這件事情就是迭代。
``````

### 枚舉(enumerate)

``````2.7.3 :008 > [1, 2, 3].each
=> #<Enumerator: [1, 2, 3]:each>
2.7.3 :013 > [1, 2, 3].each {|num| puts num + 1}
2
3
4
=> [1, 2, 3]
``````

When a block given, passes each successive array element to the block。-- form Array
Calls the given block with each key-value pair。-- form Hash

### 自己做個枚舉器。

``````2.7.3 :001 > Enumerator.is_a? Class
=> true
2.7.3 :012 > new_enume = Enumerator.new {}
``````

``````fib = Enumerator.new do |y|
a = b = 1
loop do
y << a
a, b = b, a + b
end
end

fib.take(10)
``````

"<<"，感覺上跟很眼熟。

``````2.7.3 :009 > [] << 2
=> [2]
2.7.3 :010 > [] << [2]
=> [[2]]
``````

``````fib = Enumerator.new do |y|
a = b = 1
loop do
y << a # 循環中y被賦予a值，每個變數被賦予a的值。
a, b = b, a + b # 但a與b的值，會依造此規則變化。
end
end

2.7.3 :010 > fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
``````

``````2.7.3 :042 > fib = Enumerator.new do |y|
2.7.3 :043 >   i = 0
2.7.3 :044 >   a, b = 2, 3
2.7.3 :045 >   loop do
2.7.3 :046 >     y << a
2.7.3 :047 >     a, b = b, a+b
2.7.3 :048 >     i += 1
2.7.3 :049 >     puts "某題:#{i}年後，動物有#{a}隻的問題"
2.7.3 :050 >   end
2.7.3 :051 > end
=> #<Enumerator: #<Enumerator::Generator:0x00007f9b6e469fb8>:each>
2.7.3 :052 > fib.take(10)

=> [2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
``````

`Enumerator`類別博大精深，它還有子系列是`Enumerator::`，有興趣可以先看看`Enumerator::Lazy`，簡單一點的說法是`lazy`這個子系列避免枚舉元素過多，屬於優化的一種，`Rails`內也會有所謂的`Lazy load`喔。

### Enumerable(可枚舉)

Public Instance Methods

```````all?`、`any?`、`chain`、`chunk`、`chunk_while`、`collect`、`collect_concat`、`count`、`cycle`、`deect`、`drop`、`drop_while`、`each_cons`、`each_entry`、`each_slice`、`each_with_index`、`each_with_object`、`entries`、`filter`、`filter_map`、`find`、`find_all`、`find_index`、`first`、 `flat_map`、`grep`、`grep_v`、`group_by`、`include?`、`inject`、`lazy`、`map`、`max`、`max_by`、`member?`、`min`、`min_by`、`minmax`、`minmax_by`、`none?`、`one?`、`partition`、`reduce`、`reject`、`reverse_each`、`select`、`slice_after`、`slice_before`、`slice_when`、`sort`、`sort_by`、`sum`、`take`、`take_while`、`tally`、`to_a`、`to_h`、`uniq`、`zip`
``````

``````2.7.3 :054 > ruby_chain = [1, 2].chain(3..9)
=> #<Enumerator::Chain: [[1, 2], 3..9]>
2.7.3 :056 > ruby_chain.to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
``````

### 補充一下next

``````2.7.3 :090 > arr = %w(惡魔靈魂 黑暗靈魂 黑暗靈魂2 血源詛咒 黑暗靈魂3)
=> ["惡魔靈魂", "黑暗靈魂", "黑暗靈魂2", "血源詛咒", "黑暗靈魂3"]
2.7.3 :091 > list = arr.to_enum
=> #<Enumerator: ["惡魔靈魂", "黑暗靈魂", "黑暗靈魂2", "血源詛咒", "黑暗靈魂3"]:each>
2.7.3 :092 > list.next
=> "惡魔靈魂"
2.7.3 :093 > list.next
=> "黑暗靈魂"
2.7.3 :094 > list.next
=> "黑暗靈魂2"
2.7.3 :095 > list.next
=> "血源詛咒"
2.7.3 :096 > list.next
=> "黑暗靈魂3"
2.7.3 :097 > list.next
StopIteration (iteration reached an end)
``````

``````2.7.3 :098 > games = Object.new
=> #<Object:0x00007f9b6e3f07a8>

2.7.3 :099 > def games.each
2.7.3 :100 >   p "惡魔靈魂先出在PS3"
2.7.3 :101 >   yield
2.7.3 :102 >   p "黑暗靈魂也出在PS3"
2.7.3 :103 >   yield
2.7.3 :104 >   p "黑暗靈魂2也先出在PS3"
2.7.3 :105 >   yield
2.7.3 :106 >   p "血源詛咒出在PS4"
2.7.3 :107 >   yield
2.7.3 :108 >   p "黑暗靈魂3出在PS4"
2.7.3 :109 >   yield
2.7.3 :110 >   p "下一款叫做Elden Ring"
2.7.3 :111 > end
=> :each

2.7.3 :112 > test = games.to_enum
=> #<Enumerator: #<Object:0x00007f9b6e3f07a8>:each>
2.7.3 :113 > test.next
"惡魔靈魂先出在PS3"
=> nil
2.7.3 :114 > test.next
"黑暗靈魂也出在PS3"
=> nil
2.7.3 :115 > test.next
"黑暗靈魂2也先出在PS3"
=> nil
2.7.3 :116 > test.next
"血源詛咒出在PS4"
=> nil
2.7.3 :117 > test.next
"黑暗靈魂3出在PS4"
=> nil
2.7.3 :118 > test.next
"下一款叫做Elden Ring"
StopIteration (iteration reached an end)
``````

349的題目連結:https://leetcode.com/problems/intersection-of-two-arrays/

``````# @param {Integer[]} nums1
# @param {Integer[]} nums2
# @return {Integer[]}
def intersection(nums1, nums2)

end
``````

``````2.7.3 :001 > [2, 5, 6, 3, 8] & [1, 2, 4, 7 ,4]
=> [2]
``````

``````def intersection(nums1, nums2)
nums1 & nums2
end
``````

`＆`的原理。

``````  nums1.uniq - ( nums1.uniq - nums2.uniq )
``````

#### 另外補充:intersection

``````2.7.3 :122 > [1, 2, 4, 6, 7].intersection([4, 6])
=> [4, 6]
2.7.3 :123 > [1, 2, 4, 6, 7].intersection([4, 6], [1,7])
=> []
2.7.3 :124 > [1, 2, 4, 6, 7].intersection([1, 4, 6], [1, 4, 7])
=> [1, 4]
``````

350的題目連結:https://leetcode.com/problems/intersection-of-two-arrays-ii/

``````# @param {Integer[]} nums1
# @param {Integer[]} nums2
# @return {Integer[]}
def intersect(nums1, nums2)

end
``````

`````` \$    #指針又出來了
[4, 9, 5] #arr1

[9, 4, 9, 8, 4] #arr2

{} #準備一個記錄器

#開跑
\$    #下面的陣列，我有一個4，你有沒有4？
[4, 9, 5]

[9, 4, 9, 8, 4].count(4)  #=>2  有，2個。

{4 => {arr1: 1, arr2:2}} #紀錄下來

#繼續
\$    #下面的陣列，我一個9，你?
[4, 9, 5]

[9, 4, 9, 8, 4].count(9)  #=>2  有，2個

{4 => {arr1: 1, arr2:2}, 9 => {arr1: 1, arr2: 2}} #紀錄下來

#繼續
\$    #下面的陣列，我一個5，你?
[4, 9, 5]

[9, 4, 9, 8, 4].count(5)  #=>0 ，沒有。

{4 => {arr1: 1, arr2:2}, 9 => {arr1: 1, arr2: 2}} #沒有就不必紀錄。

#不用繼續了，跑完了，即使arr2有不同元素，也成為不了交集。

#分析將
{4 => {arr1: 1, arr2:2}, 9 => {arr1: 1, arr2: 2}}
#成為一個陣列
``````

4是交集，arr2出現2次，arr1出現一次，依照規則是取小的。

``````2.7.3 :125 > x = [2 , 1].min
=> 1
2.7.3 :129 > [].push(4)*x
=> [4]
#9以此類推。
``````

349讓我們暸解交集這件事，那我們就省去了檢測這件事了。

``````def intersect(nums1, nums2)
arr = []
(nums1 & nums2).each do |num|
arr += Array.new([nums1.count(num), nums2.count(num)].min , num)
end
arr
end

#原理
2.7.3 :130 > [2, 1].min
=> 1
2.7.3 :131 > Array.new(5, 1)
=> [1, 1, 1, 1, 1]
#提醒下面寫法不行
2.7.3 :144 > [] += Array.new(4) #噴錯
2.7.3 :142 > arr = []
=> []
2.7.3 :143 > arr += arr << 4
=> [4, 4] #資料不正確。
``````

1.迭代、 枚舉

2.Leetcode350:Intersection of Two Arrays II