Destructuring tuple of tuple in closure

2019-06-20 05:46发布

问题:

I can destructure a tuple of tuple easily:

let tt = (2, (3, 4))

let (a, (b, c)) = tt
b // => 3

I'd like to do the same when declaring a closure, for example I thought I could write:

[tt].map { (a, (b, c)) in
    // Use b
}

XCode complains with "Unnamed parameters must be written with the empty name".

Only way I got it to "work" was:

[tt].map { (a, tuple: (b: Int, c: Int)) in
    // Use tuple.b
}

This has two drawbacks I'd like to avoid:

  • I need to use tuple.b instead of b
  • I need to specify the types of b and c

BTW, my use case is that I want to do a reduce with index so I'm trying using array.enumerate().reduce

回答1:

With an additional assignment line, you can assign the values in the array to (a, (b, c)) to deconstruct the tuple:

let tt1 = (2, (3, 4))
let tt2 = (5, (6, 7))

[tt1, tt2].map { tt in
    let (a, (b, c)) = tt
    print(b)
}

Output:

3
6

Alternatively:

[tt1, tt2].map {
    let (a, (b, c)) = $0
    print(b)
}


回答2:

This satisfies your first requirement but still require you to add type annonation:

typealias TupleType = (a: Int, tuple: (b: Int, c: Int))

let tt: TupleType = (2, (3, 4))

[tt].map {
    print($0.tuple.b)
}


回答3:

Another workaround:

[tt].map { a, b in
    let (b, c) = b
    print(a, b, c)
}