Sets
Overview
A set is an unordered collection that guarantees all values are unique. It is useful when you want to avoid duplicates.
In older Ruby versions, you need to add this at the top to use it.
require 'set'
To create a set from an array:
seasons = Set.new(["fall", "winter", "spring", "summer"])
puts seasons
Output:
#<Set: {"fall", "winter", "spring", "summer"}>
As mentioned, sets are used to avoid duplicates. If we try to add duplicate values, they will be ignored:
seasons.add("winter")
seasons.add("fall")
puts seasons
Output:
#<Set: {"fall", "winter", "spring", "summer"}>
Note that sets are case-sensitive, which means values like "Fall" and "fall" are considered different and can both exist in the same set.
seasons.add("Fall")
puts seasons
Output:
#<Set: {"fall", "winter", "spring", "summer", "Fall"}>
Common Set Methods
Sets provide a few familiar methods that help you inspect and work with unique values.
lengthreturns how many unique elements are in the setinclude?checks whether a value exists in the seteachiterates over every element in the set
These methods behave similarly to arrays and hashes, except they always respect the set’s uniqueness rules.
Examples:
-
Iterating over a set:
seasons = Set.new(["fall", "winter", "spring", "summer"])
seasons.each do |season|
puts season
endOutput (order is not guaranteed):
fall
winter
spring
summer -
Using
length:seasons = Set.new(["fall", "winter", "spring", "summer"])
puts seasons.lengthOutput:
4 -
Using
include?:seasons = Set.new(["fall", "winter", "spring", "summer"])
puts seasons.include?("winter")
puts seasons.include?("Winter")Output:
true
false
Adding Elements
You can add new elements using the add method.
books = Set.new(["1984", "Animal Farm"])
books.add("Brave New World")
p books
Output:
#<Set: {"1984", "Animal Farm", "Brave New World"}>
The new value is added because it did not already exist in the set. The add method also returns the set itself, which shows the updated state immediately.
If you try to add the same value again, nothing changes.
books.add("Brave New World")
p books
Output:
#<Set: {"1984", "Animal Farm", "Brave New World"}>
Duplicate values are ignored because a set always enforce uniqueness.
Removing elements
You can remove values using the delete method.
books = Set.new(["1984", "Animal Farm", "Brave New World"])
books.delete("Animal Farm")
p books
Output:
#<Set: {"1984", "Brave New World"}>
The value is removed if it exists, and the updated set is returned.
If you try to delete a value that is not in the set, Ruby does nothing and does not raise an error.
books.delete("Unknown Book")
p books
Output:
#<Set: {"1984", "Brave New World"}>
Example: Generate unique phone numbers from a file
The files can be found here: Github
In this example, we have a text file of customers who visited a shop. Each line contains a name and a phone number. For example:
Alex Tan,91234567
Jamie Lim,98765432
Alex Tan,91234567
Some entries are repeated. The task is to extract and return only the unique phone numbers.
- Read the file line by line
- Remove the newline character
- Split the line by the comma
- Add the phone number to a set
Solution:
def gen_uniq_phone_nums
phone_nums = Set.new
File.open('customers.txt').each do |customer|
newline = customer.chomp
elems = newline.split(',')
nums = elems[1]
phone_nums.add(nums)
end
phone_nums
end
report_page = gen_uniq_phone_nums
puts report_page
puts report_page.length
Running the script:
ruby main.rb
Output:
#<Set: {"91234567", "98765432", "90112233", "93445566", "95667788", "92334455", "98887766", "94556677", "97778899", "91112222", "92223333", "93334444", "94445555", "95556666", "96667777", "98889900", "90001111", "98990011", "97881234", "96782345", "95683456", "94584567", "93485678", "92386789", "91287890", "90188901"}>
To check the number of unique phone numbers:
puts report_page.length
Output:
26