Previously in Swift 2.2 I'm able to do:
extension _ArrayType where Generator.Element == Bool{
var allTrue : Bool{
return !self.contains(false)
}
}
which extends [Bool]
with .allTrue
. E.g.
[true, true, false].allTrue == false
But in Swift 3.0 I'm getting this error:
undeclared type _ArrayType
So I tried switching it to Array
and using the new keyword Iterator
extension Array where Iterator.Element == Bool
var allTrue : Bool{
return !self.contains(false)
}
}
But I got a different error complaining that I'm forcing element to be non-generic
Same-type requirement makes generic parameter 'Element' non-generic
I've also tried the solutions in this 2 years old post but to no avail.
So how does one extend arrays of primitive types like Bool in Swift 3?
Just extend the Collection or the Sequence
extension Collection where Element == Bool {
var allTrue: Bool { return !contains(false) }
}
edit/update:
Xcode 10 • Swift 4 or later
You can use Swift 4 or later collection method allSatisfy
let alltrue = [true, true,true, true,true, true].allSatisfy{$0} // true
let allfalse = [false, false,false, false,false, false].allSatisfy{!$0} // true
extension Collection where Element == Bool {
var allTrue: Bool { return allSatisfy{ $0 } }
var allFalse: Bool { return allSatisfy{ !$0 } }
}
Testing Playground:
[true, true, true, true, true, true].allTrue // true
[false, false, false, false, false, false].allFalse // true
Apple replaced _ArrayType
with _ArrayProtocol
in Swift 3.0 (see Apple's Swift source code on GitHub) so you can do the same thing you did in Swift 2.2 by doing the following:
extension _ArrayProtocol where Iterator.Element == Bool {
var allTrue : Bool { return !self.contains(false) }
}
As of Swift 3.1 (included in Xcode 8.3), you can now extend a type with a concrete constraint:
extension Array where Element == Bool {
var allTrue: Bool {
return !contains(false)
}
}
You can also extend Collection
instead of Array
, but you'll need to constrain Iterator.Element
, not just Element
.
Extending _ArrayProtocol
or Collection
didn't work for me but Sequence
did.
public extension Sequence where Iterator.Element == String
{
var allTrue: Bool { return !contains(false)
}