我在理解二维词典方面遇到了一些问题。我的函数必须返回UITableView的字典和部分。 1个模板类型可以有多个模板字符串。因此,当在fetchedData
中有2个或更多具有相似类型的文本时,它们必须在数组[String]中包含1个键 - 字符串。
从编译器的角度来看,下面的代码绝对正确。至于我,smth是错误的,但很好的自动完成让我觉得一切都好。
显然它返回一个空字典[:]
func fetchTemplates() -> Dictionary<String, [String]> {
var templates: Dictionary<String, [String]> = [:]
let fetchRequest: NSFetchRequest<Template> = Template.fetchRequest()
fetchRequest.sortDescriptors = [SortDescriptor.init(key: "templateType", ascending: true)]
let fetchedData = try! context.fetch(fetchRequest)
if (!fetchedData.isEmpty) {
for templateItem in fetchedData {
templates[templateItem.templateType!]?.append(templateItem.templateText!)
}
return templates
}
else {
return templates
}
}
P.S。 fetchedData
返回:
<Template: 0x003281h4> (entity: Template; id: 0x003281h4 <x-coredata:///Template/> ; data: {
templateText = "Example";
templateType = "First";
})
答案 0 :(得分:0)
问题是:
templates[templateItem.templateType!]
始终为nil
,因为字典为空。
因此无法追加任何内容。
答案 1 :(得分:0)
问题在于这一行:
templates[templateItem.templateType!]?.append(templateItem.templateText!)
templates
已使用此行初始化:var templates: Dictionary<String, [String]> = [:]
。此时,templates
是一个空字典。
让我们按照时间顺序将这一行分解为发生的步骤:
templateItem.templateType
,并强制解包。如果它是nil
。templateItem.templateType!
用作templates
字典的键。这将始终返回nil
。字典是空的,因此没有任何键的值,包括这个。?.append()
被调用,条件是它未在nil
上被调用。如果它在nil
上被调用,则不会发生任何事情。3是您的问题的原因。如果密钥尚不存在,则需要初始化一个新数组:
func fetchTemplates() -> Dictionary<String, [String]> {
var templates: Dictionary<String, [String]> = [:]
let fetchRequest: NSFetchRequest<Template> = Template.fetchRequest()
fetchRequest.sortDescriptors = [SortDescriptor.init(key: "templateType", ascending: true)]
let fetchedData = try! context.fetch(fetchRequest)
if (!fetchedData.isEmpty) { //see note 2
for templateItem in fetchedData {
let type = templateItem.templateType!
var array = templates[type] ?? [] //see note 1
array!.append(templateItem.templateText!)
templates[type] = array
}
return templates
}
else {
return templates
}
}
此功能可以简化:
func fetchTemplates() -> [String : [String]] {
let fetchRequest = Template.fetchRequest()
fetchRequest.sortDescriptors = [SortDescriptor(key: "templateType", ascending: true)]
let fetchedData = try! context.fetch(fetchRequest)
var templates = [String, [String]]()
for templateItem in fetchedData {
let type = templateItem.templateType!
templates[type] = (templates[text] ?? []) + [templateItem.templateText!]
}
return templates
}
可以改为使用和reduce:
func fetchTemplates() -> [String : [String]] { //see note 3
let fetchRequest = Template.fetchRequest() //see note 4
fetchRequest.sortDescriptors = [SortDescriptor(key: "templateType", ascending: true)] //see note 5
let fetchedData = try! context.fetch(fetchRequest)
return fetchedData.reduce([String, [String]]()){templates, templateItem in
(templates[templateItem.tempalteText!] ?? []) + [templateItem.templateText!]
} //see note 6
}
template[text]
不是nil
,则会将其分配给array
。否则,将新数组([]
)分配给`array。Dictionary<String, [String]>
可以写为[String : [String]]
X.init()
可以写为X()
for
循环可以更改为reduce
来电。