更优雅的表达方式((x == a && y == b)||(x == b && y == a))?

时间:2019-10-30 21:14:30

标签: swift

我正尝试在 Swift 中评估((x == a && y == b) || (x == b && y == a)),但这似乎有些冗长。有没有更优雅的方式?

4 个答案:

答案 0 :(得分:6)

如果元素可哈希,则可以使用Set

Set([a,b]) == Set([x,y])

如果没有,您可以使用tuple来摆脱许多多余的符号:

(a,b) == (x,y) || (a,b) == (y,x)

答案 1 :(得分:1)

更优雅的是。更快,但没有那么快(请注意,我认为这里的Array仍比Set好,因为它只有2个元素,但是随着n变大,显然Set会更快):

[a,b].contains(x) && [a,b].contains(y)

答案 2 :(得分:0)

一种解决方案,可用于检查两个以上的元素,并且不需要将元素设为Hashable,只需将Equatable(但是如果元素重复,则不会检查它们是否出现是否在两个数组中的次数相同,只是它们至少出现一次,就像基于Set的解决方案一样):

extension Array where Element: Equatable {
    func containsSameElements(as otherArray: Self) -> Bool {
        return otherArray.allSatisfy { contains($0) }
    }
}

用法:

[1,2,3].containsSameElements(as: [1,2,3]) // true
[1,2,3].containsSameElements(as: [1,2,3,4]) // false
[1,2,3].containsSameElements(as: [4,2,3]) // false
[1,2,3].containsSameElements(as: [3,2,1]) // true

答案 3 :(得分:0)

扩展?

struct EqualityChecker<T: Equatable> {

    private let x: T
    private let y: T

    init(_ x: T, _ y: T) {
        self.x = x
        self.y = y
    }

    static func ==(l: EqualityChecker<T>, r: EqualityChecker<T>) -> Bool {
        return (l.x == r.x && l.y == r.y) || (l.x == l.y && l.y == r.x)
    }
}

extension Numeric {

    func either(_ numbers: Self...) -> Bool {
        for number in numbers {
            if number == self { return true }
        }
        return false
    }

    func and(_ x: Self) -> EqualityChecker<Self> {
        return EqualityChecker(self, x)
    }
}

if x.either(a, b) && y.either(a, b) {
    // This is not equal to ((x == a && y == b) || (x == b && y == a))
}

if x.and(y) == a.and(b) {
    // This is equal to ((x == a && y == b) || (x == b && y == a))
}