如何创建带有设置大小的 3D 可选数组
How to create 3D array of optionals w/ set size
我如何创建一个 UInt16?
的 3 维数组,其中每个元素默认设置为 nil
?
我的尝试是
var courseInfo = UInt16?(count:10, repeatedValue: UInt16?(count:10, repeatedValue: UInt16?(count:10, repeatedValue:nil)))
虽然这似乎不起作用。有什么想法吗?
您的代码出错是因为您没有创建数组,而是将它们与 UInt16?s 混淆了。
让我们从基本情况开始,如何制作 one-dimensional 数组?
Array<UInt16?>(count: 10, repeatedValue: nil)
如果我们想要一个二维数组呢?好吧,现在我们不再初始化一个 Array<UInt16?>
我们正在初始化一个 UInt16? 数组的数组,其中每个 sub-array 都是用 UInt16?s.
初始化的
Array<Array<UInt16?>>(count:10, repeatedValue: Array<UInt16?>(count:10, repeatedValue:nil))
对 3 维情况重复此操作只需要更多相同的丑陋嵌套:
var courseInfo = Array<Array<Array<UInt16?>>>(count:10, repeatedValue: Array<Array<UInt16?>>(count:10, repeatedValue: Array<UInt16?>(count:10, repeatedValue:nil)))
我不确定这是否是最好的方法,或者对 3D 结构建模,但这是目前最接近您的代码的方法。
编辑:
马丁在评论中指出更简洁的解决方案是
var courseInfo : [[[UInt16?]]] = Array(count: 10, repeatedValue: Array(count : 10, repeatedValue: Array(count: 10, repeatedValue: nil)))
通过将类型声明移到前面,使 repeatedValue:
参数明确。
为自己构建一个抽象以允许:
var my3DArrayOfOptionalUInt16 = Matrix<UInt16?> (initial: nil, dimensions: 10, 10, 10)
使用类似的东西:
struct Matrix<Item> {
var items : [Item]
var dimensions : [Int]
var rank : Int {
return dimensions.count
}
init (initial: Item, dimensions : Int...) {
precondition(Matrix.allPositive(dimensions))
self.dimensions = dimensions
self.items = [Item](count: dimensions.reduce(1, combine: *), repeatedValue: initial)
}
subscript (indices: Int...) -> Item {
precondition (Matrix.validIndices(indices, dimensions))
return items[indexFor(indices)]
}
func indexFor (indices: [Int]) -> Int {
// Compute index into `items` based on `indices` x `dimensions`
// ... row-major-ish
return 0
}
static func validIndices (indices: [Int], _ dimensions: [Int]) -> Bool {
return indices.count == dimensions.count &&
zip(indices, dimensions).reduce(true) { [=11=] && .0 > 0 && (.0 < .1) }
}
static func allPositive (values: [Int]) -> Bool {
return values.map { [=11=] > 0 }.reduce (true) { [=11=] && }
}
}
我如何创建一个 UInt16?
的 3 维数组,其中每个元素默认设置为 nil
?
我的尝试是
var courseInfo = UInt16?(count:10, repeatedValue: UInt16?(count:10, repeatedValue: UInt16?(count:10, repeatedValue:nil)))
虽然这似乎不起作用。有什么想法吗?
您的代码出错是因为您没有创建数组,而是将它们与 UInt16?s 混淆了。
让我们从基本情况开始,如何制作 one-dimensional 数组?
Array<UInt16?>(count: 10, repeatedValue: nil)
如果我们想要一个二维数组呢?好吧,现在我们不再初始化一个 Array<UInt16?>
我们正在初始化一个 UInt16? 数组的数组,其中每个 sub-array 都是用 UInt16?s.
Array<Array<UInt16?>>(count:10, repeatedValue: Array<UInt16?>(count:10, repeatedValue:nil))
对 3 维情况重复此操作只需要更多相同的丑陋嵌套:
var courseInfo = Array<Array<Array<UInt16?>>>(count:10, repeatedValue: Array<Array<UInt16?>>(count:10, repeatedValue: Array<UInt16?>(count:10, repeatedValue:nil)))
我不确定这是否是最好的方法,或者对 3D 结构建模,但这是目前最接近您的代码的方法。
编辑:
马丁在评论中指出更简洁的解决方案是
var courseInfo : [[[UInt16?]]] = Array(count: 10, repeatedValue: Array(count : 10, repeatedValue: Array(count: 10, repeatedValue: nil)))
通过将类型声明移到前面,使 repeatedValue:
参数明确。
为自己构建一个抽象以允许:
var my3DArrayOfOptionalUInt16 = Matrix<UInt16?> (initial: nil, dimensions: 10, 10, 10)
使用类似的东西:
struct Matrix<Item> {
var items : [Item]
var dimensions : [Int]
var rank : Int {
return dimensions.count
}
init (initial: Item, dimensions : Int...) {
precondition(Matrix.allPositive(dimensions))
self.dimensions = dimensions
self.items = [Item](count: dimensions.reduce(1, combine: *), repeatedValue: initial)
}
subscript (indices: Int...) -> Item {
precondition (Matrix.validIndices(indices, dimensions))
return items[indexFor(indices)]
}
func indexFor (indices: [Int]) -> Int {
// Compute index into `items` based on `indices` x `dimensions`
// ... row-major-ish
return 0
}
static func validIndices (indices: [Int], _ dimensions: [Int]) -> Bool {
return indices.count == dimensions.count &&
zip(indices, dimensions).reduce(true) { [=11=] && .0 > 0 && (.0 < .1) }
}
static func allPositive (values: [Int]) -> Bool {
return values.map { [=11=] > 0 }.reduce (true) { [=11=] && }
}
}