集合是一种不可变、无序的数据结构,其中的值都是唯一的。集合里的所有元素都必须是同一类型。
gleam/set 模块定义了 Set 类型,并提供了处理集合的各种函数。
你可以用set.to_list和set.from_list在数组和集合之间相互转换。集合中元素的顺序是不确定的。
set.from_list([2, 3, 3, 3, 1, 1, 2])
// -> set.from_list([1, 2, 3])
set.to_list(set.from_list([2, 3, 3, 3, 1, 1, 2]))
// -> [1, 2, 3]
你可以用set.new、set.insert和set.delete来创建和填充集合。
set.new()
// -> set.from_list([])
let eighty_eight = set.from_list([88])
set.insert(eighty_eight, 88)
// -> set.from_list([88])
set.insert(eighty_eight, 89)
// -> set.from_list([88, 89])
set.delete(eighty_eight, 89)
// -> set.from_list([88])
你可以用set.contains和set.size这两个函数来查询集合的内容。
set.contains(eighty_eight, 88)
// -> True
set.size(eighty_eight)
// -> 1
集合可以用set.union和set.intersection来合并。
let a = set.from_list([1, 5, 10])
let b = set.from_list([1, 2, 3, 4, 5])
set.union(a, b)
// -> set.from_list([1, 2, 3, 4, 5, 10])
set.intersection(a, b)
// -> set.from_list([1, 5])
你可以对集合进行过滤。
let is_small = fn(n) { n <= 3 }
set.filter(b, is_small)
// -> set.from_list([1, 2, 3])
你对 Blorkemon™️ 卡牌的怀旧之情丝毫没有减弱的迹象,甚至还重新开始收集它们,还拉上朋友们一起。
在这个练习中,卡牌收藏用Set(String)表示,因为当你的目标是收集所有已存在的卡牌时,重复的卡牌并不重要。
你非常希望朋友们也加入你的 Blorkemon™️ 狂热,最好的办法就是送他们一张卡牌,帮他们开启自己的收藏。
实现new_collection,它把一张卡牌变成一个收藏。
new_collection("Newthree")
// -> set.from_list(["Newthree"])
一旦你有了一个收藏,它就有了自己的生命,必须不断成长。
实现add_card,它接收一张卡牌和一个收藏,返回一个包含两个值的元组:一个Bool,表示这张卡牌是否已经在收藏中;以及加入了这张卡牌后的收藏。
add_card(set.from_list(["Newthree"]), "Scientuna")
// -> #(False, set.from_list(["Newthree", "Scientuna"]))
既然你的朋友们又为 Blorkemon™️ 疯狂了,你就可以借此通过交换卡牌来扩充自己的收藏。
并不是每次交换都值得做,有些甚至根本做不了。 你不能交换一张自己没有的卡牌,也不应该用一张卡牌去换你已经有的卡牌。
实现trade_card,它接收要交换的两张卡牌(你的和对方的)以及你当前的收藏。
返回值是一个包含两个值的元组:一个Bool,说明这次交换是否可行且值得;以及如果你真的完成了交换,最终会得到的收藏(即使实际上并不可行)。
trade_card("Scientuna", "Newthree", set.from_list(["Scientuna"]))
// -> #(True, set.from_list(["Newthree"]))
你和热爱 Blorkemon™️ 的朋友们聚在一起,想知道哪些卡牌最常见。
实现boring_cards,它接收一个收藏列表,返回一个排序后的卡牌列表,这些卡牌是所有收藏都有的。
boring_cards([set.from_list(["Scientuna"]), set.from_list(["Newthree", "Scientuna"])])
// -> ["Scientuna"]
你和朋友们加起来是否拥有全部的 Blorkemon™️ 卡牌?
实现total_cards,它接收一个收藏列表,返回所有收藏中不同卡牌的总数。
total_cards([set.from_list(["Scientuna"]), set.from_list(["Newthree", "Scientuna"])])
// -> 2
你的侄子马上就要来看你了,你想给他留下深刻印象。 小孩子都喜欢亮闪闪的东西,对吧? Blorkemon™️ 卡牌也可以是闪光的!
实现shiny_cards,它接收一个收藏,返回一个集合,其中包含所有以"Shiny "开头的卡牌。
shiny_cards(set.from_list(["Newthree", "Scientuna", "Shiny Scientuna"]))
// -> set.from_list(["Shiny Scientuna"])