如何将数组转换为元组?

时间:2014-07-14 21:36:44

标签: arrays swift type-conversion tuples

我只想将数组转换为Swift中的元组;如下所示:

>>> myArray = [1,2,3,4,5]
>>> mytuple = tuple(myArray)
>>> mytuple
(1, 2, 3, 4, 5)

最简单的方法是什么?

(我今天才开始学习Swift,所以我非常非常新。)

5 个答案:

答案 0 :(得分:21)

如果你愿意做一些低等级的魔术,那实际上是非常可能的。但是,如果元组具有集合类型,我认为它不起作用。这主要是为了与C库进行交互。

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))

这里可以找到更多这样的东西: https://codereview.stackexchange.com/questions/84476/array-to-tuple-in-swift/84528#84528


因为我们70%的人都是高度视觉的人:

enter image description here

答案 1 :(得分:14)

您不能这样做,因为元组的大小是其类型的一部分,而对于数组则不是这样。如果您知道数组的长度,则可以let myTuple = (myArray[0], myArray[1], ...)。或者,您可以从一开始就围绕元组构建您的架构。你想做什么?

这是许多其他语言中常见的问题。见How do I convert a list to a tuple in Haskell?

答案 2 :(得分:1)

这是将数组数据复制到元组的通用解决方案。我无法解决的唯一问题是检查元组中的元素类型和数组中的元素。

/// 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 }
    }
}

答案 3 :(得分:0)

害怕不安全的指针?或者需要支持内部不同类型的元组?

它也可以这样做:

public extension Array {

    public var tuple: Any? {
        switch count {
        case 0:
            return ()
        case 1:
            return (self[0])
        case 2:
            return (self[0], self[1])
        case 3:
            return (self[0], self[1], self[2])
        case 4:
            return (self[0], self[1], self[2], self[3])
        case 5:
            return (self[0], self[1], self[2], self[3], self[4])
        default:
            return nil
     }
 }

因为输入这个内容可能有点容易出错,所以write tests最好这样做,以确保返回正确的元组。

我在ArrayPlusTuple中使用了这种方法。

因此,您不必自己编写此功能,只需将pod 'ArrayPlusTuple'添加到您的pod文件中即可免费获得此测试功能。

答案 4 :(得分:0)

如果您要同时从数组中提取多个值,也许 以下代码可以为您提供帮助

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])
    }
}

然后您可以像这样使用它

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

您甚至可以编写一个代码生成器来生成扩展代码