【问题标题】:Swift Dictionary of ArraysSwift 数组字典
【发布时间】:2015-01-04 18:59:59
【问题描述】:

我正在制作一个具有不同游戏模式的应用,每个游戏模式都有一些分数。我正在尝试将所有分数存储在数组字典中,其中字典的键是游戏的 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).

【问题讨论】:

  • 这很糟糕,因为数组中只有一个值和j == 1。换句话说,这是一个越界错误。我正在尝试理解您的代码,但遇到了麻烦。确切地说,这应该做什么?

标签: arrays swift dictionary


【解决方案1】:

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

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

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

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

另外,一般来说,每当您使用数组下标时,您都会冒着意外解决像这里这样的越界索引的风险。有很多替代方案意味着实际使用 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 循环更好)

【讨论】:

  • 别觉得愚蠢,我们都做过很多次了 :)。这样做的寓意是下标很容易搞砸,并且有很多选择(请参阅我的编辑)
猜你喜欢
  • 2015-05-10
  • 2018-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
  • 2014-09-12
  • 2014-08-23
  • 1970-01-01
相关资源
最近更新 更多