In Swift, you can add a new element to an existing set by using either the insert()
method or the update()
method.
Using the insert() method
The insert()
method returns a tuple containing a Boolean value (that indicates whether the element was inserted) and the inserted element. If the element was not already present in your set, the method returns (true, newMember)
. If an element equal to newMember
was already present in the set, the method returns (false, oldMember)
, where oldMember
is the element that was equal to newMember
. In some cases, oldMember
may be distinguishable from newMember by identity comparison or some other means.
The words above might be boring and confusing. Here’s an example:
var colors = Set(["red", "green", "blue"])
// using insert() method
let result = colors.insert("yellow")
print(result) // (inserted: true, memberAfterInsert: "yellow")
print(colors) // ["red", "green", "blue", "yellow"]
let result2 = colors.insert("green")
print(result2) // (inserted: false, memberAfterInsert: "green")
print(colors) // ["red", "green", "blue", "yellow"]
Using the update() method
The update()
method does the following:
- Inserting a new element into your set if it is not already present, and returns
nil
. - Replacing an existing element if it has an equal value with the element you want to add and returns that replaced element.
Example:
var words: Set<String> = ["Sling", "Academy", "Swift", "iOS"]
// add a new element
var result1 = words.update(with: "Demon")
print(result1 as Any) // nil
print(words) // ["Sling", "iOS", "Swift", "Academy", "Demon"]
// add a value that already exists
words.update(with: "Sling")
var result2 = words.update(with: "Sling")
print(result2 as Any) // Optional("Sling")
print(words) // ["Sling", "iOS", "Swift", "Academy", "Demon"]
You may think “replacing an existing element if it has an equal value with the element you want to add” make no sense. I’m sorry if that was confusing. Let me explain in more detail in the next section of this article.
Advanced: More about the update() method
A set is a collection of unique elements, so it cannot have duplicate values. However, two elements can be equal in value but different in some other way, such as identity or reference. For example, if you have a set of custom objects that conform to the Hashable
protocol, you can define how they are compared for equality and hashed. If you insert or update an element that has the same hash value and is equal to an existing element in the set, the existing element will be replaced by the new one. This may or may not change the actual contents of the set, depending on how you define equality for your custom objects.
A code example is worth more than a thousand words:
// A custom class that conforms to Hashable
class Person: Hashable {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
// Define how two persons are compared for equality
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.name == rhs.name && lhs.age == rhs.age
}
// Define how a person is hashed
func hash(into hasher: inout Hasher) {
hasher.combine(name)
hasher.combine(age)
}
}
// Create a set of persons
var persons: Set<Person> = [
Person(name: "Wolf", age: 99),
Person(name: "Voldermort", age: 68),
Person(name: "Dracula", age: 1100),
]
// Create a new person with the same name and age as "Wolf"
// I think "Wolf" is a nice name for a man
// There is also a character named "Wolf" in the game "Sekiro: Shadows Die Twice"
let newWolf = Person(name: "Wolf", age: 99)
// Update the set with the new person
let oldWolf = persons.update(with: newWolf)
// Print the old and new persons
print("Old person: \(oldWolf!.name), \(oldWolf!.age)")
print("New person: \(newWolf.name), \(newWolf.age)")
// Check if they are equal in value
print("Are they equal? \(oldWolf == newWolf)") // true
// Check if they are identical (same reference)
print("Are they identical? \(oldWolf === newWolf)") // false
// Print the persons in the set after updating
for person in persons {
print("\(person.name), \(person.age)")
}
/*
Voldermort, 68
Wolf, 99
Dracula, 1100
*/
That’s it. Happy coding & have a nice day!