Reputation: 12559
Is there a way to extend an Array when the element is a type of tuple ?
public extension Array where Element: (timeZoneName: String, formattedName: String){
}
This declaration returns 4 errors:
- Statement cannot begin with a closure expression
- Braced block statements is an unused closure
- Expected '{' in extension
- Expected identifier for type name
I can't tell if the errors shown are accurate. Any ideas?
Upvotes: 5
Views: 2112
Reputation: 1236
It's now possible in Swift 3.1.
extension Array where Element == (String, String) {
...
}
Upvotes: 4
Reputation: 2341
Swift 3 version of appzYourLife's answer:
extension Sequence where Iterator.Element == Tuple2 {
func foo() {}
}
Upvotes: 4
Reputation: 14334
You can't add specific typing like extension Array where Element == Int
because this would transform the generic Array into a non-generic version.
You will see an error something like same-type requirement makes generic parameter 'Element' non-generic
Edit
It does actually seem legit (at least in Swift 2.2) to do:
typealias tzTuple = (timeZoneName: String, formattedName: String) extension Array where Element: tzTuple { }
You will have to see if this works in runtime though.
I was checking this in a Playground and at present, Playgrounds are not yet fully functional with Swift 2.2-dev
I would suggest this instead:
typealias tzTuple = (timeZoneName: String, formattedName: String) extension Array { func formattedName(index: Int) -> String? { if self[index] is tzTuple { return (self[index] as! tzTuple).formattedName } return nil } }
will allow you to do
let foo = [(timezoneName: "PST", formattedName: "Pacific Standard Time"),(timezoneName: "AEST", formattedName: "Australian Eastern Time")] print(foo.formattedName(0))
Upvotes: 1
Reputation: 59506
Since (AFAIK) the Tuple
type does not conform to a Protocol
(and does not even have a name) it's very hard to do what you need.
This is the closest I could get (maybe others can provide more elegant solutions).
First of all lets define a couple of typealiases
typealias Tuple2 = (Any, Any)
typealias Tuple3 = (Any, Any, Any)
Yes, some readers now understand where I am going and probably don't like it...
I don't like it neither
Now let's extend the protocol SequenceType
adding the foo
method when the Element
of the sequence is Tuple2
...
extension SequenceType where Generator.Element == Tuple2 {
func foo() {}
}
or Tuple3
extension SequenceType where Generator.Element == Tuple3 {
func foo() {}
}
Next lets define and populate an array of Tuple2
let list: [Tuple2] = [(1,2)]
Now the extension is applied and we can write
list.foo()
This does work only if the array is explicitly declared as [Tuple2]
(or [Tuple3]
).
Something like this does not work
let list = [(1,2)]
list.foo() // compile error
Upvotes: 3