How can I convert an array to a tuple?

It's actually quite possible, if you are willing to do some low level magic. I don't think it works if the tuple has a collection type, though. This is mainly for interacting with C libraries.

typealias TupleType = (UInt8, UInt8, UInt8)

var array = [2, 3, 4] as [UInt8]
var tuple = UnsafeMutablePointer<StepsType>(malloc(UInt(sizeof(TupleType))))
memcpy(tuple, array, UInt(array.count))

More of this stuff can be found here: https://codereview.stackexchange.com/questions/84476/array-to-tuple-in-swift/84528#84528


Because 70% of us are highly visual beings:

enter image description here


You can't do this because the size of a tuple is part of its type, and this isn't true for an array. If you know the array's length, you can just do let myTuple = (myArray[0], myArray[1], ...). Or you can build your architecture around tuples from the beginning. What are you trying to do?

This is a common problem which occurs in lots of other languages. See How do I convert a list to a tuple in Haskell?


if what you want to do is extract multiple value from array at the same time, maybe the following code could help you

extension Array {
    func splat() -> (Element,Element) {
        return (self[0],self[1])
    }

    func splat() -> (Element,Element,Element) {
        return (self[0],self[1],self[2])
    }

    func splat() -> (Element,Element,Element,Element) {
        return (self[0],self[1],self[2],self[3])
    }

    func splat() -> (Element,Element,Element,Element,Element) {
        return (self[0],self[1],self[2],self[3],self[4])
    }
}

then you can use it like this

  let (first,_,third) = ( 0..<20 ).map { $0 }.splat()

you can even write a codegen to generate the extension code


This my universal solution for copy array data to tuple. The only problem that I could not solve is to check the type of the element in the tuple and the element from the array.

/// Unsafe copy array to tuple
func unsafeCopyToTuple<ElementType, Tuple>(array: inout Array<ElementType>, to tuple: inout Tuple) {
    withUnsafeMutablePointer(to: &tuple) { pointer in
        let bound = pointer.withMemoryRebound(to: ElementType.self, capacity: array.count) { $0 }
        array.enumerated().forEach { (bound + $0.offset).pointee = $0.element }
    }
}