我有大量数据采用以下形式:[四个整数的数组],{与该整数数组相关的字符串集}。例如,
[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]
一起工作,但我不明白为什么。
matches2![0]
有效,而matches2[0]
没有?答案 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]