Any way to iterate a tuple in swift?
Yes, you can!
func iterate<C,R>(t:C, block:(String,Any)->R) {
let mirror = reflect(t)
for i in 0..<mirror.count {
block(mirror[i].0, mirror[i].1.value)
}
}
And voila!
let tuple = ((false, true), 42, 42.195, "42.195km")
iterate(tuple) { println("\($0) => \($1)") }
iterate(tuple.0){ println("\($0) => \($1)")}
iterate(tuple.0.0) { println("\($0) => \($1)")} // no-op
Note the last one is not a tuple so nothing happens (though it is a 1-tuple or "Single" which content can be accessed .0
, reflect(it).count
is 0).
What's interesting is that iterate()
can iterate even other types of collection.
iterate([0,1]) { println("\($0) => \($1)") }
iterate(["zero":0,"one":1]) { println("\($0) => \($1)") }
And that collection includes class
and struct
!
struct Point { var x = 0.0, y = 0.0 }
class Rect { var tl = Point(), br = Point() }
iterate(Point()) { println("\($0) => \($1)") }
iterate(Rect()) { println("\($0) => \($1)") }
Caveat: the value passed as the 2nd argument of the block is type Any
. You have to cast it back to the values with original type.
You can using reflection Swift 5
Try this in a Playground:
let tuple = (1, 2, "3")
let tupleMirror = Mirror(reflecting: tuple)
let tupleElements = tupleMirror.children.map({ $0.value })
tupleElements
Output:
Swift does not currently support iterating over tuples.
The biggest reasons are:
- There is no way at runtime to determine the number of elements in a tuple
- There is no way to access an element at a specific index except for the compile time accessors like
tupleList.0
. You would really want a subscripttupleList[0]
but that is not provided to us
Frankly, I can't see a reason that you would use a tuple instead of an Array if you want to iterate over it.
It doesn't make sense to iterate over a tuple because:
- Tuples always have a fixed length and each element has a fixed type
- You can name each tuple member with a name you can use to access it later
Arrays are well made to iterate over:
- Arbitrary length
- Can store multiple types using a common superclass or AnyObject
- Can be declared as a literal in a similar fashion to tuples:
var list = ["A",2.9,3,8,5,6,7,8,9]