i am currently working on an App that needs to compare three Variables with each other.
Rules for Comparison: The result should only be true if: All three variables are equal OR All three variables are different
My first idea was something like this, but I hope there is a more elegant solution for this:
if (value1 == value2 && value2 == value3) || (value1 != value2 && value2 != value3 && value3 != value1) {
// True
} else {
// False
}
I would be really happy if someone of you can think of a more elegant solution and share it with me. Thanks for your help in advance!
If your values are also Hashable
you can use a Set
. Given the fact that a Set
discards duplicate values, you can simplify your check to something like this:
let valuesArray = [value1, value2, value3]
let valuesSet = Set(valuesArray)
if valuesSet.count == 1 || valuesSet.count == valuesArray.count {
// True
} else {
// False
}
For a one-off, that's not too bad.
The more "general" solution is kind of messy, because it needs to track 2 different boolean variables, and handle empty collections correctly.
extension Sequence where Element: Equatable {
func classifyElementEquality() -> (allEqual: Bool, allUnequal: Bool) {
var iterator = self.makeIterator()
guard let first = iterator.next() else {
return (true, true) // all empty
}
return AnyIterator(iterator)
.reduce(into: (allEqual: true, allUnequal: true)) { acc, element in
if first == element {
acc.allUnequal = false
} else {
acc.allEqual = false
}
}
}
}
let (value1, value2, value3) = (1, 2, 3)
let result = [value1, value2, value3].classifyElementEquality()
if result.allEqual || result.allUnequal {
print("They're either all equal, or all unequal")
} else {
print("Some of them are different")
}
It can get a bit simpler if this algorithm targets Collection
insteaad of Sequence
, because accessing the first element is easier without needing to manually manage an iterator.
extension Collection where Element: Equatable {
func classifyElementEquality() -> (allEqual: Bool, allUnequal: Bool) {
guard let first = self.first else {
return (true, true) // all empty
}
return self
.dropFirst()
.reduce(into: (allEqual: true, allUnequal: true)) { acc, element in
if first == element {
acc.allUnequal = false
} else {
acc.allEqual = false
}
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.