× 說心事 政治時事 生活 運動 汽車 機車 自行車 相機 科技 理財 旅遊美食 娛樂 健康 美麗時尚 人際關係 文學故事 《思書》
吃喝玩樂 《思書》


Ruby 好用的 Set 與應用


紅寶鐵軌客
來關注...
關注/停止關注:紅寶鐵軌客
關注有什麼好處?:當作者有新文章發佈時,「思書」就會自動通知您,讓您更容易與作者互動。
×
現在就加入《思書》,你就可以關注本作者了!
《思書》是一個每個人的寫作與論壇平台,特有的隱私管理,讓你寫作不再受限,討論更深入真實,而且免費。 趕快來試試!
還未加入《思書》? 現在就登錄! 已經加入《思書》── 登入
Rails 使用中,折磨中,享受中......
34   0  
2019/03/26


Ruby 中被遺忘的珍珠:Set(集合)

很多人可能都忘了 Ruby 中有內建很好用的「Set(集合)」程式庫,忘記它的理由可能只是它因為是在標準程式庫中,使用時必須要 require 進來,可是在 Rails 中,直接用就可以了。

Ruby 的 Set(集合)非常好用,特別是與 Array 有幾乎相同的運算方式,Set(集合)是使用 Hash 來儲存,所以很多 hash 的運用也通用,Set(集合)與 Array 有以下兩個最重要最大的不同:

  1. Set(集合)會自動移除重複的 elements 元素
  2. Set(集合)沒有排列順序

在很多情況下,適當的使用 Set(集合)與 Array (陣列)可以大幅的減少開發的難度,兩者的混用,更是一個強強結合。

我們先來看一下 Set(集合)的基本運算,對應到離散數學上的集合運算:

> require 'set'

# 聯集 OR
> Set[1,2,3] | Set[3,4,5]
=> #<Set: {1, 2, 3, 4, 5}>

# 交集 AND
> Set[1,2,3] & Set[2,3,4,5]
=> #<Set: {2, 3}>

# 互斥或 XOR (觀察到 Set 沒有排列順序了嗎!)
> Set[1,2,3] ^ Set[3,4,5]
=> #<Set: {4, 5, 1, 2}>

# 加 +
> Set[1,2,3,4] + Set[3,4,5]
=> #<Set: {1, 2, 3, 4, 5}>

# 減 -
> Set[1,2,3,4] - Set[3,4,5]
=> #<Set: {1, 2}>

# 只儲存不同的元素
> Set[1,2,3,3,2,1]
=> #<Set: {1, 2, 3}>

# 判斷相等
> Set[1,2,3] == Set[3,1,2]
=> true

# 判斷不等
> Set[1,2,3] != Set[3,1,2]
=> false

# 子集 subset
>Set[1,2,3] <( Set[3,1,2,4])
=> true
> Set[1,2,3] <( Set[3,1,2])
=> false

# 真子集 proper subset
> Set[1,2,3] <=( Set[3,1,2,4])
=> true
> Set[1,2,3] <=( Set[3,1])
=> false

# 也可以用 Enumerable
Set[2,4,8,16].each {|el| puts el}
#=> 2
#   4
#   8
#   16 

這只是列出了一小部分,更多就請看一下文件了。

應用:

實務上,我們有很多地方可以用到,特別是如果結合 Array 跟 Set,例如:我們要一個沒有重複的 elements 元素的 Array,要移除相同的元素,可能不是那麼簡單,現在,我們只要用 set,輕輕鬆鬆就可以辦到!如下:

Array 移除相同的元素
# 在 Array 中移除相同的元素
> a = [1,2,3,3,2,1]
=> [1, 2, 3, 3, 2, 1]
> a.to_set.to_a
=> [1, 2, 3]

用 Set 跟 Array 來玩字串,也很有趣,有想過如何找出一段文字中,所有不同的單字嗎?轉一轉就好了! 

一段文字中,找出所有不同的單字
# 找出字串中不同的字
s="Set implements a collection of unordered values with no duplicates. This is a hybrid of Array's intuitive inter-operation facilities and Hash's fast lookup."

> s.gsub(".","").split(' ').to_set.to_a.reject(&:empty?)
=> ["Set", "implements", "a", "collection", "of", "unordered", "values", "with", "no", "duplicates", "This", "is", "hybrid", "Array's", "intuitive", "inter-operation", "facilities", "and", "Hash's", "fast", "lookup"]

> s.gsub(".","").split(' ').to_set.to_a.reject(&:empty?).join(", ")
=> "Set, implements, a, collection, of, unordered, values, with, no, duplicates, This, is, hybrid, Array's, intuitive, inter-operation, facilities, and, Hash's, fast, lookup"

是不是很簡單又有趣!我很喜歡 Set(集合),我以前幾乎都忘了它的存在,它的沒有重複元素的特性,在很多運用上,可以簡化很多開發難度。

有要注意的點嗎?

當然使用上還是有要注意的,我目前想到最大的問題就是,因爲 Set(集合)沒有固定排列順序,這是跟 Array 最大的不同點,所以使用上要稍微小心一點,很容易跟 Set 跟 Array 混淆,不過,如果有學過離散數學,這問題就不大了。  我前幾天還在跟人聊天,說上課時學了一學期的離散數學,好像都沒用到過,沒想到,馬上就用到了,真是墨菲定律啊。

備註,及一些好用的參考:

  1. 內容有部分來自:When Is a Ruby Set Better Than a Ruby Array?


喜歡作者的文章嗎?馬上按「關注」,當作者發佈新文章時,思書™就會 email 通知您。

思書是公開的寫作平台,創新的多筆名寫作方式,能用不同的筆名探索不同的寫作內容,無限寫作創意,如果您喜歡寫作分享,一定要來試試! 《 加入思書》

思書™是自由寫作平台,本文為作者的個人立場與意見。


文章資訊

分類於:
標籤:
日期:
創作於:2019/03/26,最後更新於:2019/03/26。


分享:
關於作者

很久以前就是個「寫程式的」,其實,什麼程式都不熟⋯⋯
就,這會一點點,那會一點點⋯⋯




參與討論!
×
現在就加入《思書》,馬上參與討論!
《思書》是一個每個人的寫作與論壇平台,特有的隱私管理,用筆名來區隔你討論內容,讓你的討論更深入,而且免費。 趕快來試試!
還未加入《思書》? 現在就登錄! 已經加入《思書》── 登入