多维数组不允许我通过循环赋值?

时间:2015-12-11 20:27:46

标签: arrays swift multidimensional-array

我有一小段代码如下:

func initAllLabels() {

    var scoreLabels:[[[SKLabelNode]]] = []

    for (var x = 0; x < modesInGame; x++) {
        for (var y = 0; y < levelsInMode; y++) {
            for (z = 0; z < labelsInLevel; z++) {
                scoreLabels[x][y][z] = SKLabelNode(fontNamed: "Font")
            }
        }
    }
}

所以我要做的就是为每种游戏模式存储我的所有标签。我尝试使用多维数组的原因是因为每个级别(3-5)我会有几个标签,我想像这样访问它们:

updateText(scoreLabels[currentMode][currentLevel][thisLabel])

访问当前标签的所有标签,如下所示:

for label in labelsInLevel:
    label.hidden = false

问题在于,当我尝试在initAllLabels游戏开始时创建所有标签时,我得到一个&#34;索引超出范围&#34;循环中第一次运行时出错(索引:0)。我认为问题是因为我需要&#34;追加&#34;在设置其内容之前到数组,这是对的吗?我将如何在像我这样的数组结构中实现这一目标?

2 个答案:

答案 0 :(得分:2)

在更新其中的位置之前,您需要将数组初始化为给定的大小。从单维案例开始可能有所帮助:

var labels: [SKLabelNode] = [] // creates an empty array
// since the array is empty, this will generate an index out of range error:
labels[0] = SKLabelNode(fontNamed: "Font")

相反,您需要使用要添加的元素扩展数组。例如,

for _ in 0..<labelsInLevel {
    labels.append(SKLabelNode(fontNamed: "Font"))
}

_表示“我不关心每次迭代的实际数量 - 通常如果你想知道这是i围绕你编写的循环for i in 0..<n Array 1}})

虽然有更好的方法可以做到这一点。但是要小心,其中一个是count的初始值设定项,需要repeatedValuelet labels = Array(count: labelsInLevel, repeatedValue: SKLabelNode(fontNamed: "Font”))

SKLabelNode

let variableOne = SKLabelNode(fontNamed: "Foo") let variableTwo = variableOne // variableTwo now refers to the same instance of SKLabelNode variableTwo.fontName = "Bar" print(variableOne) // fontName will now be “Bar” even though this was // done via variableTwo 是参考类型。这意味着变量仅引用实例,将一个变量分配给另一个变量仅复制引用。例如:

repeatedValue

您可以使用上面的for代码获得相同的效果。标签创建一次,并且多次插入相同的引用。更改数组中一个标签上的属性,然后更改它们。请注意,SKLabelNode循环版本会出现此问题。每次循环时,都会创建一个新的repeatedValue实例。他们不会被分享。

在不使用for循环的情况下创建的map初始值设定项的替代方法是使用(0..<labelsInLevel).map { _ in SKLabelNode(fontNamed: "Font") }

for

这里,就像在SKLabelNode循环版本中一样,每次都会创建一个新的_实例。

(同样,我们使用map表示我们不关心迭代次数)

最后,要创建包含内部循环的嵌套多维数组,您可以多次运行var scoreLabels = (0..<modesInGame).map { _ in (0..<levelsInMode).map { _ in (0..<labelsInLevel).map { _ in SKLabelNode(fontNamed: "Font") } } }

finalAge = int(age) + factor   #finalAge is an integer

答案 1 :(得分:-2)

如果您希望所有SKLabelNode指向不同的SKLabelNodes,则需要像这样初始化3D数组:

func initAllLabels() {

    var scoreLabels = [[[SKLabelNode]]](count: modesInGame, repeatedValue:
        [[SKLabelNode]](count: levelsInMode, repeatedValue:
        (0..< labelsInLevel).map { _ in SKLabelNode(fontNamed: "Font") }))
}

repeatedValue是您存储在单元格中的类型(类型或值),计数表示您希望将其存储在数组中的次数。

PS:这个答案是用Xcode Playground测试的,效果非常好。

我按照Airspeed Velocity的评论编辑了我的答案。