I have two NSCountedSets and need to subtract them. For the sake of clarity, I am using a simple struct with one property as the objects:
struct MyStruct {
let name: String
init(_ name: String) {
self.name = name
}
}
func subtract(_ set1: NSCountedSet, _ set2: NSCountedSet) -> NSCountedSet {
var result = NSCountedSet()
for e in set1 {
let count1 = set1.count(for: e)
let count2 = set2.count(for: e)
let newCount = count1 - count2
if newCount > 0 {
for _ in 1 ... newCount {
result.add(e)
}
}
}
return result
}
let set1 = NSCountedSet(array: [MyStruct("A"), MyStruct("A"), MyStruct("A"), MyStruct("B"), MyStruct("C"), MyStruct("C")])
let set2 = NSCountedSet(array: [MyStruct("A"), MyStruct("B"), MyStruct("C")])
let set3 = subtract(set1, set2) // expected result: ["A", "A", "C"]`
print(set3.count(for: MyStruct("A"))) // observed result: 0 (expected 2)
print(set3.count(for: MyStruct("B"))) // observed result: 0 (expected 0)
print(set3.count(for: MyStruct("C"))) // observed result: 0 (expected 1)
But if I for instance use:
let set1 = NSCountedSet(array: ["A", "A", "A", "B", "C", "C"])
let set2 = NSCountedSet(array: ["A", "B", "C"])
I get the expected result.
I suspect that each MyStruct("A") etc is actually not equal to the other ones since they are recreated. Which is what I see when I add a print statement, count1 is always 1 and count2 is always 0
So maybe there is a way that I can count the number of MyStruct by checking the name property, is that possible?
If not, is there maybe any other solution?
You need to make your type conform to
Hashableto makeNSCountedSetcompare its elements based on their properties.There's also no need to define a
subtractmethod,NSCountedSetalready inheritsminusfrom itsNSMutableSetsuperclassBe aware that
minusmutates the set it's called on in place, rather than returning a new instance.If you want to declare a non-mutating variant of
minuswithout having to reimplement its logic, you can simply do that by copying the set, the callingminuson the copy.