如何检查 Swift 5 中的 3 个变量是否相等?

How to Check if 3 Variables are equal or not equal to each other in Swift 5?

我目前正在开发一个需要相互比较三个变量的应用程序。

Rules for Comparison: The result should only be true if: All three variables are equal OR All three variables are different

我的第一个想法是这样的,但我希望有一个更优雅的解决方案:

if (value1 == value2 && value2 == value3) || (value1 != value2 && value2 != value3 && value3 != value1) {
    // True
} else {
    // False
}

如果你们中有人能想到更优雅的解决方案并与我分享,我将非常高兴。 提前感谢您的帮助!

如果您的值也是 Hashable,您可以使用 Set。鉴于 Set 丢弃重复值这一事实,您可以将检查简化为如下所示:

let valuesArray = [value1, value2, value3]
let valuesSet = Set(valuesArray)

if valuesSet.count == 1 || valuesSet.count == valuesArray.count {
    // True
} else {
    // False
}

对于 one-off,还不错。

更“通用”的解决方案有点混乱,因为它需要跟踪 2 个不同的布尔变量,并正确处理空集合。

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")
}

如果此算法的目标是 Collection 而不是 Sequence,它会变得更简单一些,因为访问第一个元素更容易,无需手动管理迭代器。

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
                }
            }
    }
}