因为我有:
struct S {
var num = 0
}
我想实现一个函数allEqual()作为Array<S>
的扩展,所以我可以做像
var s1 = S()
var s2 = S()
var s3 = S()
var equality = [s1,s2,s3].allEqual()
答案 0 :(得分:3)
答案 1 :(得分:1)
我为SequenceType
为Element
的任何Equatable
创建了一个懒惰的扩展程序。在Swift中,优良作法是使代码完全按照它可以工作的方式工作:为了能够得到所有元素是否相等,它必须是一系列相等的值。这是代码:
extension SequenceType where Generator.Element : Equatable {
var allEqual : Bool {
var gen = generate() // Generate the sequence for the first element
return gen.next().map { fst in // Get first element and map it (when existing)
!contains { fst != $0 } // To whether self doesn't contain any elements unequal to first
} ?? true // When first is nil, return true
}
}
或者您也可以进行更多迭代(基本相同我认为更快?):
extension SequenceType where Generator.Element : Equatable {
var allEqual : Bool {
var gen = generate()
let first = gen.next()
return !contains { $0 != first }
}
}
此外,您应该使您的结构符合Equatable
协议,如下所示:
func ==(lhs: S, rhs: S) -> Bool {
return lhs.x == rhs.x
}
因为every value type should be equatable显然在你的代码中完全有意义。
以下是一些测试代码:
[S(x: 3), S(x: 3), S(x: 3)].allEqual // true
[S(x: 5), S(x: 3), S(x: 3)].allEqual // false
[S(x: 5), S(x: 5)].allEqual // true
[S(x: 0)].allEqual // true
[S]().allEqual // true
请注意,它是懒惰的,这意味着只要有一个不等于第一个元素的元素,它就会返回false,所以如果你有这样的东西:
let longList = [S(x: 5)] + [S](count: 100000, repeatedValue: S(x: 4))
// [{x 5}, {x 4}, {x 4}, {x 4}, {x 4}, {x 4}, {x 4}, ...
longList.allEqual // false
将返回第二个元素,因为已经存在相等性
编辑:我之前的功能不必要地复杂化了。新的还是懒得更短答案 2 :(得分:0)
在最新的Swift 3.1中。您可以在具体类型扩展上执行相同类型的约束。所以在你的情况下,你可以这样做:
extension Array where Element == S {
func allEqual() -> Bool {
...
}
}