我只想在 Swift 中将数组转换为元组;像下面这样:
>>> myArray = [1,2,3,4,5]
>>> mytuple = tuple(myArray)
>>> mytuple
(1, 2, 3, 4, 5)
最简单的方法是什么?
(我今天才开始学习 Swift,所以我非常非常新)。
如果你愿意做一些低级魔法,这实际上是很有可能的。不过,我认为如果元组具有 collection 类型,它就不起作用。这主要是为了与 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% 的人都是高度视觉动物:
你不能这样做,因为元组的大小是其类型的一部分,而数组则不然。如果你知道数组的长度,你就可以这样做
let myTuple = (myArray[0], myArray[1], ...)
。或者您可以从一开始就围绕元组构建您的架构。你想做什么?
这是许多其他语言中出现的常见问题。请参阅如何在 Haskell 中将列表转换为元组?
如果你想要做的是同时从数组中提取多个值,也许 下面的代码可以帮助你
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()
您甚至可以编写代码生成器来生成扩展代码
这是我将数组数据复制到元组的通用解决方案。我无法解决的唯一问题是检查元组中元素的类型和数组中元素的类型。
/// 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 }
}
}
害怕不安全的指针?或者需要支持内部不同类型的元组?
也可以这样做:
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
}
}
因为输入此内容可能有点容易出错,所以最好为此编写测试以确保返回正确的元组。
我在 ArrayPlusTuple 中使用了这种方法。
因此,您无需自己编写此功能,只需将
pod 'ArrayPlusTuple'
添加到您的 pod 文件中即可免费获得此经过测试的功能。
使用新的 Swift 5.9 通用参数包,解决方案要好得多: