如何创建具有设置大小的可选项的3D数组

时间:2016-01-07 22:29:30

标签: swift multidimensional-array optional uint16

我如何创建一个具有设定大小的UInt16?三维数组,其中每个元素默认设置为nil

我的尝试是

var courseInfo = UInt16?(count:10, repeatedValue: UInt16?(count:10, repeatedValue: UInt16?(count:10, repeatedValue:nil)))

虽然这似乎不起作用。有什么想法吗?

2 个答案:

答案 0 :(得分:4)

您的代码出错是因为您没有创建数组,而是将它们与UInt16混合在一起。

让我们从基础案例开始,你如何制作一维数组呢?

Array<UInt16?>(count: 10, repeatedValue: nil)

如果我们想要一个二维数组怎么办?那么,现在我们不再初始化Array<UInt16?>我们正在初始化一个UInt16数组的数组?其中每个子数组都是用UInt16初始化的。

Array<Array<UInt16?>>(count:10, repeatedValue: Array<UInt16?>(count:10, repeatedValue:nil))

对于三维情况重复这一点只需要更多相同的丑陋嵌套:

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:参数明确无误,这是有效的。

答案 1 :(得分:1)

为自己构建一个抽象来允许:

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) { $0 && $1.0 > 0 && ($1.0 < $1.1) }
  }

  static func allPositive (values: [Int]) -> Bool {
    return values.map { $0 > 0 }.reduce (true) { $0 && $1 }
  }
}