Data.Set
Module Data.Set
cho ta các tập hợp. Giống như tập hợp toán học ấy. Tất cả các phần tử trong tập hợp đều là duy nhất. Và vì bản chất là chúng được lập bằng cấu trúc cây (rất giống với ánh xạ trong Data.Map
), nên chúng có thứ tự. Việc kiểm tra quan hệ thuộc, chèn phần tử, xóa phần tử, v.v. nhanh hơn nhiều so với những thao tác tương tự trên danh sách. Phép thao tác thường gặp nhất khi làm việc với tập hợp là chèn vào tập hợp, kiểm tra xem phần tử có thuộc tập hợp hay không, và chuyển đổi tập hợp thành danh sách.
Vì các tên hàm trong Data.Set
xung đột [trùng lặp] nhiều với tên trong Prelude
và Data.List
, nên ta cần nhập có chọn lọc.
Hãy viết câu lệnh nhập này trong file mã lệnh:
import qualified Data.Set as Set
Rồi sau đó nạp file mã lệnh trong GHCI.
Giả sử rằng ta có hai đoạn văn bản chữ. Ta cần tìm ra xem những kí tự nào được dùng trong cả hai đoạn đó.
text1 = "I just had an anime dream. Anime... Reality... Are they so different?" text2 = "The old man left his garbage can out and now his trash is all over my lawn!"
Hàm fromList
hoạt động rất giống với những gì bạn trông đợi. Nó nhận vòa một danh sách rồi chuyển đổi nó thành một tập hợp.
ghci> let set1 = Set.fromList text1 ghci> let set2 = Set.fromList text2 ghci> set1 fromList " .?AIRadefhijlmnorstuy" ghci> set2 fromList " !Tabcdefghilmnorstuvwy"
Như bạn đã thấy, các phần tử được xếp thứ tự và mỗi phần tử là duy nhất. Bây giờ hãy dùng hàm intersection
để xem những phần tử nào có chung trong cả hai tập hợp này.
ghci> Set.intersection set1 set2 fromList " adefhilmnorstuy"
Ta có thể dùng hàm difference
để xem những chữu cái nào có trong tập hợp thứ nhất nhưng không có trong tập hợp thứ hai, và ngược lại.
ghci> Set.difference set1 set2 fromList ".?AIRj" ghci> Set.difference set2 set1 fromList "!Tbcgvw"
Hoặc là ta có thể xem những chữ cái duy nhất dùng trong hai câu này [không cần chung] bằng hàm union
.
ghci> Set.union set1 set2 fromList " !.?AIRTabcdefghijlmnorstuvwy"
Các hàm null
, size
, member
, empty
, singleton
, insert
và delete
, tất cả đều hoạt động theo cách bạn trông đợi.
ghci> Set.null Set.empty True ghci> Set.null $ Set.fromList [3,4,5,5,4,3] False ghci> Set.size $ Set.fromList [3,4,5,3,4,5] 3 ghci> Set.singleton 9 fromList [9] ghci> Set.insert 4 $ Set.fromList [9,3,8,1] fromList [1,3,4,8,9] ghci> Set.insert 8 $ Set.fromList [5..10] fromList [5,6,7,8,9,10] ghci> Set.delete 4 $ Set.fromList [3,4,5,4,3,4,5] fromList [3,5]
Ta cũng có thể kiểm tra các mối quan hệ tập con hoặc tập con thực sự. Tập hợp A được gọi là tập con của tập B nếu B chứa tất cả những phần tử có trong A. Tập A được gọi là tập con thực sự của tập B nếu B chứa tất cả những phần tử của A, ngoài ra còn những phần tử khác nữa.
ghci> Set.fromList [2,3,4] `Set.isSubsetOf` Set.fromList [1,2,3,4,5] True ghci> Set.fromList [1,2,3,4,5] `Set.isSubsetOf` Set.fromList [1,2,3,4,5] True ghci> Set.fromList [1,2,3,4,5] `Set.isProperSubsetOf` Set.fromList [1,2,3,4,5] False ghci> Set.fromList [2,3,4,8] `Set.isSubsetOf` Set.fromList [1,2,3,4,5] False
Ta cũng có thể map
[ánh xạ] trên tập hợp và filter
[lọc] chúng.
ghci> Set.filter odd $ Set.fromList [3,4,5,6,7,2,3,4] fromList [3,5,7] ghci> Set.map (+1) $ Set.fromList [3,4,5,6,7,2,3,4] fromList [3,4,5,6,7,8]
Tập hợp thường được dùng để gạt một tập hợp những phần tử trùng lặp khỏi một danh sách gốc bằng cách đầu tiên là chuyển nó về một tập hợp, bằng hàm fromList
và rồi chuyển ngược nó về bằng toList
. Hàm nub
trong Data.List
đã làm việc đó, nhưng việc gạt bỏ trùng lặp trên danh sách lớn sẽ được thực hiện nhanh hơn nhiều nếu bạn nhồi nó vào một tập hợp rồi chuyển ngược về danh sách bằng cách dùng nub
. Nhưng để dùng nub
chỉ cần kiểu của các phần tử danh sách thuộc về lớp Eq
, còn nếu muốn nhồi các phần tử vào tập hợp thì kiểu của danh sách phải thuộc về Ord
.
ghci> let setNub xs = Set.toList $ Set.fromList xs ghci> setNub "HEY WHATS CRACKALACKIN" " ACEHIKLNRSTWY" ghci> nub "HEY WHATS CRACKALACKIN" "HEY WATSCRKLIN"
Nhìn chung, setNub
nhanh hơn nub
khi hoạt động trên danh sách lớn, song như bạn có thể thấy, nub
bảo toàn thứ tự các phần tử trong danh sách, còn setNub
thì không.
ConversionConversion EmoticonEmoticon