Scene:
let superTrue = [1,2,3,3]
let superFalse = [1,2,3]
let sub = [2,3,3]
Requirements:
sub
is subset of superTrue
but not superFalse
.
The wrong code:
print(Set(sub).isSubset(of: superTrue)) // true
print(Set(sub).isSubset(of: superFalse)) // true
because Set(sub)
is [2,3]
, removes the duplicated 3
Don't remove the duplicate, and compute subset, any ideas?
CodePudding user response:
Set
will always remove duplicates by its nature.
One of the options would be to count occurrences of all elements in all three arrays:
let subCounts = sub.reduce(into: [:]) { $0[$1, default: 0] = 1 }
let superTrueCounts = superTrue.reduce(into: [:]) { $0[$1, default: 0] = 1 }
let superFalseCounts = superFalse.reduce(into: [:]) { $0[$1, default: 0] = 1 }
And then to check if values for all keys of the wannabe subarray equals or are less than the values of the same keys of the "super" array:
subCounts
.keys
.allSatisfy { subCounts[$0, default: 0] <= superTrueCounts[$0, default: 0] }
subCounts
.keys
.allSatisfy { subCounts[$0, default: 0] <= superFalseCounts[$0, default: 0] }
This will gives the output you expect (as far as I understood the questions).
Note 1. Since you originally tried to use Set
, I assumed the order doesn't matter and you only care about specific elements and the number of their occurrences.
Note 2. The elements should be Equatable
.