學習軌道
/
Elm
Elm
/
練習
/
全部抓到手!
全部抓到手!

全部抓到手!

學習練習

簡介

Set

Set a是一串型別為a的不重複值。 這些值的型別必須是comparable(Int、Float、Time、Char、String,以及由可比較型別組成的元組或陣列)。

你可以用Set.toList和Set.fromList把陣列和集合互相轉換。 由於Set的內部結構,可以保證從Set.fromList取得的陣列是排序好的。

Set.fromList [2, 3, 3, 3, 1, 1, 2]
    --> Set.fromList [1, 2, 3]

Set.toList (Set.fromList [2, 3, 3, 3, 1, 1, 2])
    --> [1, 2, 3]

你可以用Set.empty、Set.singleton、Set.insert和Set.remove來建立集合,並在其中加入或移除元素。

Set.empty
    --> Set.fromList []

Set.singleton "hi"
    --> Set.fromList ["hi"]

eightyEight = Set.singleton 88

Set.insert 88 eightyEight
    --> Set.fromList [88]

Set.insert 89 eightyEight
    --> Set.fromList [88, 89]

Set.remove 88 eightyEight
    --> Set.fromList []

Set.remove 89 eightyEight
    --> Set.fromList [88]

你可以用Set.member、Set.isEmpty和Set.size這幾個函式來查詢集合的內容。

Set.member 88 eightyEight
    --> True

Set.isEmpty eightyEight
    --> False

Set.size eightyEight
    --> 1

集合可以用Set.union、Set.intersect和Set.diff來合併。

a = Set.fromList [1, 10, 100]
b = Set.fromList [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Set.union a b
    --> Set.fromList [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100]

Set.intersect a b
    --> Set.fromList [1, 10]

Set.diff a b
    --> Set.fromList [100]

Set.diff b a
    --> Set.fromList [2, 3, 4, 5, 6, 7, 8, 9]

你可以篩選和分割集合。

even n = modBy 2 n == 0

Set.filter even b
    --> Set.fromList [2, 4, 6, 8, 10]

Set.partition even b
    --> (Set.fromList [2, 4, 6, 8, 10], Set.fromList [1, 3, 5, 7, 9])

說明

你對 Blorkemon™️ 卡牌的懷舊之情絲毫沒有減退的跡象,你甚至又開始收集它們了,還拉著朋友一起加入。

在這個練習中,Card的收藏是以 Set Card表示,因為當你的目標是收集所有現有的卡牌時,重複的卡牌並不重要。

1. 開始建立收藏

你真的很想讓朋友一起陷入 Blorkemon™️ 的瘋狂,而最好的方式就是送他們一張卡牌,幫他們的收藏踏出第一步。

實作 newCollection,它會把一張卡牌變成一個收藏。

newCollection "Newthree"
    --> Set.fromList ["Newthree"]

2. 壯大收藏

一旦你有了收藏,它就會有自己的生命,必須不斷成長。

實作 addCard,它接收一張 Card 和一個收藏,並回傳一個 Tuple,裡面有兩個值:一個 Bool,表示這張 Card 是否已經在收藏中,以及加入這張卡牌後的收藏。

addCard "Scientuna" (Set.fromList ["Newthree"])
    --> (False, Set.fromList ["Newthree", "Scientuna"])

3. 開始交換

既然你的朋友們又對 Blorkemon™️ 瘋狂了,你就可以利用這點,透過交換卡牌來壯大自己的收藏。

不是每一筆交換都值得做,有些甚至根本做不到。 你不能交換一張自己沒有的卡牌,也不該拿卡牌去換一張自己已經有的。

實作 tradeCard,它接收要交換的兩張卡牌(你的和對方的)以及你目前的收藏。 回傳值是一個 Tuple,包含兩個值:一個 Bool,說明這筆交換是否可行且值得,以及你完成交換後會得到的收藏(即使實際上根本不可行)。

tradeCard "Scientuna" "Newthree" (Set.fromList ["Scientuna"])
    --> (True, Set.fromList ["Newthree"])

4. 每種只能有一張

你在跳蚤市場找到一批舊卡牌。 你必須把這些卡牌排序並移除重複的,才能把這個陣列和你的收藏做比較。

實作 removeDuplicates,它會把一個卡牌陣列排序,並回傳一個排序過、不重複的卡牌陣列。

removeDuplicates ["Newthree", "Newthree", "Newthree", "Scientuna"]
    --> ["Newthree", "Scientuna"]

5. 別人沒有的卡牌

是時候為自己的收藏感到開心了。

實作 extraCards,它接收你的收藏和另一個收藏,並回傳對方的收藏中沒有的卡牌數量。

extraCards (Set.fromList ["Scientuna"]) (Set.fromList ["Newthree", "Scientuna"])
    --> 0

6. 每個人都有的卡牌

你和一群熱愛 Blorkemon™️ 的朋友聚在一起,想知道哪些卡牌最常見。

實作 boringCards,它接收一個收藏的陣列,並回傳一個排序過的卡牌陣列,這些卡牌是所有收藏都有的。

boringCards [Set.fromList ["Scientuna"], Set.fromList ["Newthree", "Scientuna"]]
    --> ["Scientuna"]

7. 全部的卡牌

你和朋友加起來,是否擁有全部的 Blorkemon™️ 卡牌?

實作 totalCards,它接收一個收藏的陣列,並回傳所有收藏中不同卡牌的總數。

totalCards [Set.fromList ["Scientuna"], Set.fromList ["Newthree", "Scientuna"]]
    --> 2

8. 閃亮取勝

你的侄子不久後要來拜訪你,你想讓他留下深刻印象。 小孩子都喜歡閃亮亮的東西,對吧? Blorkemon™️ 卡牌也可以閃亮亮!

實作 splitShinyCards,它接收一個收藏,並回傳一個 Tuple,裡面有兩個排序過的卡牌陣列:一個包含所有以 "Shiny" 開頭的卡牌,另一個包含其他卡牌。

splitShinyCards (Set.fromList ["Newthree", "Scientuna", "Shiny Scientuna"])
    --> (["Shiny Scientuna"], ["Newthree", "Scientuna"])
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Elm Exercism

準備好開始 全部抓到手! 了嗎?

註冊 Exercism,透過 28 個概念110 個練習 和真人引導來學習並精通 Elm,全部免費。