Swift 数组字典

Swift Dictionary of Arrays

我正在制作一个具有不同游戏模式的应用程序,每个游戏模式都有一些分数。我试图将所有分数存储在数组字典中,其中字典的键是游戏的 id(字符串),关联的数组包含该游戏模式的分数列表。但是当我尝试将数组的值初始化为随机值时,Swift 中断,出现以下错误。这段代码将在操场上中断。我做错了什么?

let modes = ["mode1", "mode2", "mode3"]
var dict = Dictionary<String, [Int]>()

for mode in modes
{
    dict[mode] = Array<Int>()
    for j in 1...5
    {
        dict[mode]?.append(j)
        let array:[Int] = dict[mode]!
        let value:Int = array[j]      //breaks here
    }
}

错误:

Execution was interrupted, reason: EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP, subcode=0x0).

你的问题是数组下标是从零开始的。所以当你写:

var a: [Int] = []
for i in 1...5 {
    a.append(42)
    println(a[i])
}

你会得到一个运行时错误,因为第一次循环你在下标 a[1] 时只有一个 a[0]。在您的代码中,您需要执行 for j in 0..<5let value = array[j-1].

顺便说一句,尽管 dict[mode]! 是绝对安全的(因为您刚刚添加了它),但最好避免这种习惯,因为有一天您的代码不会像您想象的那样正确,然后 ! 会在你的脸上爆炸。 几乎总有一种更好的方式来写你想要的东西而不需要!

此外,一般来说,每当您使用数组下标时,您都会冒着因意外处理此处这样的越界索引而导致意外搞砸的风险。有很多选择意味着实际上使用 a[i] 很容易避免:

  • 如果您想要集合的索引(如数组),而不是:

    for i in 0..<a.count { }
    

    你可以写

    for i in indices(a) { }
    
  • 如果要对数组中的元素进行编号,而不是

    for i in indices(a) { println("item \(i) is \(a[i])" }
    

    你可以写

    for (i, elem) in enumerate(a) { println("item \(i) is \(elem)") }
    

    如果集合恰好有一个Int作为索引(比如Array),你可以使用i作为索引,但是如果没有(比如作为 String) 获取索引和元素的替代方法是:

    let s = "hello"
    for (idx, char) in Zip2(indices(s),s) { }
    
  • 如果您想要数组的第一个或最后一个元素,而不是:

    if a.count > 0 { let x = a[0] }
    if a.count > 0 { let x = a[a.count - 1] }
    

    你可以写

    if let first = a.first { let x = first }
    if let last = a.last { let x = first }
    
  • 一般情况下,mapfilterreduce 优于 for 循环(但不要执着于此,有时 for 循环更好)