Using Sets, I can conveniently insert an element into the set, and also check whether the element was in the set using one call to insert:
let array = [1,2,3,4,4,2,5,3,6,7,1]
var set = Set<Int>()
for item in array {
// set.insert not only inserts the item, but also tells me whether the item was in set before the insert
if set.insert(item).inserted {
print("Encountered new item: \(item)")
} else {
print("\(item) has already been encountered!")
}
}
Output:
Encountered new item: 1
Encountered new item: 2
Encountered new item: 3
Encountered new item: 4
4 has already been encountered!
2 has already been encountered!
Encountered new item: 5
3 has already been encountered!
Encountered new item: 6
Encountered new item: 7
1 has already been encountered!
However, if I rewrite the the same logic using IndexSet:
let array = [1,2,3,4,4,2,5,3,6,7,1]
var set = IndexSet()
for item in array {
// set.insert not only inserts the item, but also tells me whether the item was in set before the insert
if set.insert(item).inserted {
print("Encountered new item: \(item)")
} else {
print("\(item) has already been encountered!")
}
}
The output becomes:
Encountered new item: 1
Encountered new item: 2
Encountered new item: 3
Encountered new item: 4
Encountered new item: 4
Encountered new item: 2
Encountered new item: 5
Encountered new item: 3
Encountered new item: 6
Encountered new item: 7
Encountered new item: 1
It appears that the tuple returned by IndexSet.insert always matches (true, _), but even so, the set's count is not increased. I must check set.contains(item) before insert to produce the desired output.
Question: Is this intended behaviour for IndexSet?
I know that IndexSet is a Cocoa API, and not native to Swift, so I thought perhaps there is some special semantics that IndexSet has about what it means for two numbers to be "the same" that I'm not aware of. I also looked for bug reports on bugs.swift.org about IndexSet, but I didn't find anything about insert always returning true.