集合 - 从字典中的字符串数组中提取

时间:2015-10-02 20:05:24

标签: arrays dictionary collections swift2

我有大量数据采用以下形式:[四个整数的数组],{与该整数数组相关的字符串集}。例如,

[1,1,1,8],{"(1+1+1)*8"}

[1,1,2,8],{"1*(1 + 2)*8","(1 + 2)/(1/8)"}

我有成千上万的这些对保存在外部文本文件中,并且需要能够根据密钥中的四个整数来调用各个行。一个解决方案似乎是在发布时将文本文件读入字典,但是字典的明显表述

let myDict2:Dictionary<Array<Int>, Array <String>> = [[1,1,1,8]: ["(1+1+1)*8"],[1,1,2,8]: ["1*(1 + 2)*8","(1 + 2)/(1/8)"]]

失败,因为&#34;键入&#39;数组&#39;不符合协议&#39; Hashable&#39;。&#34;

但是我们可以将键从一个整数数组转换为一个字符串,并尝试使用它:

let myDict2:Dictionary<String, Array <String>> = ["1118": ["(1+1+1)*8"],"1128": ["1*(1 + 2)*8","(1 + 2)/(1/8)"]]

没有错误,甚至看起来我们可以用

提取结果
let matches2=myDict2["1128"] // correctly returns ["1*(1 + 2)*8", "(1 + 2)/(1/8)"]

但是当我们尝试使用matches2[0]从该答案中提取元素时,我们得到"Cannot subscript a value of type '[String]?'"

在我的键盘上随机敲击,我让它与matches2![0]一起工作,但我不明白为什么。

  1. 有没有办法让我原来的字典尝试[整数数组,一组字符串]有效?
  2. 在第二个公式[字符串,字符串集]中,为什么matches2![0]有效,而matches2[0]没有?
  3. 字典是一种合理的方法吗,还是有其他一些数据结构可以更好地实现我的目标?

1 个答案:

答案 0 :(得分:1)

我先回答你的第二个问题:

let matches2=myDict2["1128"] // returns an Optional<Array<String>>

每次dict[key]调用都会返回一个可选值,因为字典可能不包含该键。所以你必须先解开它

matches2[0]  // error
matches2![0] // ok

现在回答您的其他问题:Dictionary适用于必须根据密钥维护数据唯一性的情况。例如,如果每个人都需要一个唯一的社会安全号码,则应将SSN用作字典键,将人员信息用作其值。我不知道你的要求是什么,所以我会把它留给它。

将四个数字连接成一个字符串是一个坏主意,除非所有数字都有相同的数字。例如,(1,23,4,5)(12,3,4,5)将生成相同的字符串。

Array<Int>未实现Hashable协议,因此您必须提供自己的包装器。这是我的尝试:

struct RowID : Hashable {
    var int1: Int
    var int2: Int
    var int3: Int
    var int4: Int

    init(_ int1: Int, _ int2: Int, _ int3: Int, _ int4: Int) {
        self.int1 = int1
        self.int2 = int2
        self.int3 = int3
        self.int4 = int4
    }

    var hashValue : Int {
        get {
            return "\(int1),\(int2),\(int3),\(int4)".hashValue
        }
    }
}

// Hashable also requires you to implement Equatable
func ==(lhs: RowID, rhs: RowID) -> Bool {
    return lhs.int1 == rhs.int1
            && lhs.int2 == rhs.int2
            && lhs.int3 == rhs.int3
            && lhs.int4 == rhs.int4
}

let myDict: [RowID: [String]] = [
    RowID(1,1,1,8): ["(1+1+1)*8"],
    RowID(1,1,2,8): ["1*(1 + 2)*8","(1 + 2)/(1/8)"]
]

let id = RowID(1,1,2,8)
let value = myDict[id]![0]

// You can also access it directly
let value2 = myDict[RowID(1,1,1,8]]![0]