Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any way to iterate a tuple in swift?

Tags:

swift

I am curious how to do a for loop with a tuple in swift.

I know that to access each member you can use dot notation using the index number

var tupleList = ("A",2.9,3,8,5,6,7,8,9)

for each in tupleList {
    println(each)
}

//Error: Type does not conform to protocol sequence

like image 852
Chéyo Avatar asked Jun 19 '14 04:06

Chéyo


People also ask

Can you iterate a tuple?

We can iterate over tuples using a simple for-loop. We can do common sequence operations on tuples like indexing, slicing, concatenation, multiplication, getting the min, max value and so on.

How do you iterate through the tuple of tuples?

Easiest way is to employ two nested for loops. Outer loop fetches each tuple and inner loop traverses each item from the tuple. Inner print() function end=' ' to print all items in a tuple in one line.

Is tuple ordered in Swift?

You use tuples in Swift to make ordered, comma-separated lists of values.


3 Answers

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.

like image 168
dankogai Avatar answered Oct 06 '22 12:10

dankogai


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:

enter image description here

like image 23
Menno Avatar answered Oct 06 '22 11:10

Menno


Swift does not currently support iterating over tuples.

The biggest reasons are:

  1. There is no way at runtime to determine the number of elements in a tuple
  2. 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 subscript tupleList[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:

  1. Tuples always have a fixed length and each element has a fixed type
  2. You can name each tuple member with a name you can use to access it later

Arrays are well made to iterate over:

  1. Arbitrary length
  2. Can store multiple types using a common superclass or AnyObject
  3. Can be declared as a literal in a similar fashion to tuples: var list = ["A",2.9,3,8,5,6,7,8,9]
like image 12
drewag Avatar answered Oct 06 '22 12:10

drewag