Swift 为单个键添加多个定义
好吧,假设我有一本字典:Swift 为单个键添加多个定义,swift,Swift,好吧,假设我有一本字典: var-someDict=[String:String]() 我可以通过以下方式添加密钥和定义: someDict[“微笑”]=“:) 但是假设我想给“微笑”添加另一个定义,比如:D someDict[“微笑”]?+=“:D” 现在我想要的是 [“微笑”:“,”:D“]。我知道这行不通,因为,分隔符 所以我需要一种方法来使用[“微笑”:[“:)”,“:D”],这样我就可以使用someDict[“微笑”][1],这将等于:D 我不会列出我尝试过的东西,因为这些都是无用的,
var-someDict=[String:String]()
我可以通过以下方式添加密钥和定义:
someDict[“微笑”]=“:)
但是假设我想给“微笑”添加另一个定义,比如:D
someDict[“微笑”]?+=“:D”
现在我想要的是
[“微笑”:“,”:D“]
。我知道这行不通,因为,
分隔符
所以我需要一种方法来使用[“微笑”:[“:)”,“:D”]
,这样我就可以使用someDict[“微笑”][1]
,这将等于:D
我不会列出我尝试过的东西,因为这些都是无用的,我也不知道我在做什么
总之,
我希望能够在字典中添加键,可能是在for循环中添加键。您需要的只是这种类型的数据格式:
var someDict = [String: [String]]()
初始化它:
someDict["Smiling"] = [":)"]
这样您就可以做到:
someDict["Smiling"]?.append(":D")
并称之为:
someDict["Smiling"]?[1] //returns ":D"
编辑:
可能值得一提的是,正如@dfri所述,使用显式数组索引调用(“[1]”)是不安全的,因为如果数组没有两个或多个值,这将失败。一个“快速”解决方案是通过检查数组中是否存在无效索引来验证索引
这可能看起来像这样(感谢@Hamish提供的代码):
你真的需要把它包在你自己的结构中。确切地说,你如何做取决于你想要的语义学,但是把这样的事情作为起点:
struct MyDictArray {
private var _data: [String : [String]] = [:]
mutating func append(key: String, value: String) {
if let existingEntry = self._data[key] {
self._data[key] = existingEntry + [value]
} else {
self._data[key] = [value]
}
}
subscript(key: String) -> [String] {
get {
if let existingEntry = self._data[key] {
return existingEntry
} else {
return []
}
}
set {
if let existingEntry = self._data[key] {
self._data[key] = existingEntry + newValue
} else {
self._data[key] = newValue
}
}
}
subscript(key: String, index: Int) -> String? {
if index < self[key].count {
return self[key][index]
} else {
return nil
}
}
}
var someDict = MyDictArray()
someDict["Smiling"] = [":)"]
someDict.append(key: "Smiling", value: "D")
someDict["Smiling"]
someDict["Smiling", 1] // Safe indexing
struct MyDictArray{
私有变量数据:[字符串:[字符串]]=[:]
mutating func append(键:字符串,值:字符串){
如果让existingEntry=self.\u数据[键]{
self.\u数据[键]=现有条目+[值]
}否则{
self.\u数据[键]=[值]
}
}
下标(键:字符串)->[字符串]{
得到{
如果让existingEntry=self.\u数据[键]{
返回现有条目
}否则{
返回[]
}
}
设置{
如果让existingEntry=self.\u数据[键]{
self.\u数据[键]=现有条目+新值
}否则{
self.\u数据[键]=新值
}
}
}
下标(键:String,索引:Int)->String{
如果索引
你是对的,你需要[String:[String]]
,这会起作用,但你需要告诉我们使用someDict[“微笑”]?有什么问题。首先
,someDict[“微笑”]?.last
等。最后两个代码行都不会编译。通过键访问字典值会生成可选值,因此您需要在对其进行变异之前将其展开(例如,使用可选绑定,someDict[“smilling”]?.append(“:D”)
和someDict[“smilling”?[1]
)。请注意,后一种按索引显式访问是不安全的,因为如果索引超出边界,它将导致运行时异常。@dfri抱歉忽略了这一点。它现在已修复。@dfri关于它不安全的第二点,我如何改进它?在调用之前检查数组的长度是一个好主意吗?检查数组长度是一个好主意一种方法是在通过索引访问之前进行“经典C/C++”数组长度验证。另一种更快速的方法是使用array
方法从“不安全”(未验证)创建安全索引一个;。在您的示例中,索引1
与上一个有效索引相同,因此简单地使用可选的last
属性可能是最好的选择。@dfri哦,好吧,这很酷,我以前没有见过。我已更新了我的答案以反映此方法:)
let idx = 1
if let arr = someDict["Smiling"], arr.indices.contains(idx) {
print(arr[idx]) // :D
}
struct MyDictArray {
private var _data: [String : [String]] = [:]
mutating func append(key: String, value: String) {
if let existingEntry = self._data[key] {
self._data[key] = existingEntry + [value]
} else {
self._data[key] = [value]
}
}
subscript(key: String) -> [String] {
get {
if let existingEntry = self._data[key] {
return existingEntry
} else {
return []
}
}
set {
if let existingEntry = self._data[key] {
self._data[key] = existingEntry + newValue
} else {
self._data[key] = newValue
}
}
}
subscript(key: String, index: Int) -> String? {
if index < self[key].count {
return self[key][index]
} else {
return nil
}
}
}
var someDict = MyDictArray()
someDict["Smiling"] = [":)"]
someDict.append(key: "Smiling", value: "D")
someDict["Smiling"]
someDict["Smiling", 1] // Safe indexing