从字典 [Swift 3] 生成部分 headers
Generate section headers from dictionary [Swift 3]
我有一组具有以下结构类型的字典(已经排序):
[
[
"id": 1,
"name": "ItemA",
"url": "http://url.com"
],
[
"id": 32,
"name": "ItemB",
"url": "http://url.com"
],
...
]
声明为 AnyObject 的字典数组:
var arrayApps = [[String:AnyObject]]()
这个字典数组是使用 SwiftyJson 生成的:
[..]
if let resData = swiftyJsonVar["data"].arrayObject {
self.arrayItems = resData as! [[String:AnyObject]]
}
[..]
我的目标是使用部分 headers 来显示这些项目,但在尝试弄清楚并寻找答案后,我无法继续前进。
我尝试按字母对字典进行分组以获得如下结果:
[
"A":{[foo1],[foo2]},
"D":{[foo3],[foo5]},
"F":{[foo4],[foo6]}
...
]
但运气不好,我总是以错误告终,因为我的数组包含 "Optionals"。
总结:
我如何根据 TableView 中的名称生成按字母顺序排列的部分 headers 使用一组未像上面 Swift 3 中给出的字典那样分组的字典?
提前致谢!!
您可以使用 Array 的 .sorted(by: )
方法来比较数组中的元素。
这会产生一个 sortedArray:
let sortedArray = arrayOfApps.sorted(by: {([=10=]["name"] as! String) <= (["name"] as! String)})
如果 itemName 不是字符串,这将崩溃,但我将其留给您处理任何错误。例如将其更改为:
[=11=]["name"] as? String ?? ""
编辑:
// 删除示例并添加扩展以创建所需结果
我找到了我的一个旧项目,我在其中编写了这样的扩展。对它进行了一些更改以满足您的需要,请告诉我它是否还需要更改:
extension Array {
func sectionTitlesForArray(withName name: (Element) -> String) -> Array<(title: String, elements: NSMutableArray)> {
var sectionTitles = Array<(title: String, elements: NSMutableArray)>()
self.forEach({ element in
var appended = false
sectionTitles.forEach({ title, elements in
if title == name(element) {
elements.add(element)
appended = true
}
})
if appended == false {
sectionTitles.append((title: name(element), elements: [element]))
}
})
return sectionTitles
}
}
// Usage single letter as Section title:
let sectionTitles = arrayOfApps.sectionTitlesForArray(withName: {
let name = [=12=]["name"] as! String
return String(name[name.startIndex])
})
// Quick dirty pretty-print:
sectionTitles.forEach({ sectionTitle in
print("Section title: \(sectionTitle.title) \n")
sectionTitle.elements.forEach({ object in
let element = object as! Dictionary<String,Any>
print("Element name: \(element["name"]!)")
})
print("")
})
我有一组具有以下结构类型的字典(已经排序):
[
[
"id": 1,
"name": "ItemA",
"url": "http://url.com"
],
[
"id": 32,
"name": "ItemB",
"url": "http://url.com"
],
...
]
声明为 AnyObject 的字典数组:
var arrayApps = [[String:AnyObject]]()
这个字典数组是使用 SwiftyJson 生成的:
[..]
if let resData = swiftyJsonVar["data"].arrayObject {
self.arrayItems = resData as! [[String:AnyObject]]
}
[..]
我的目标是使用部分 headers 来显示这些项目,但在尝试弄清楚并寻找答案后,我无法继续前进。 我尝试按字母对字典进行分组以获得如下结果:
[
"A":{[foo1],[foo2]},
"D":{[foo3],[foo5]},
"F":{[foo4],[foo6]}
...
]
但运气不好,我总是以错误告终,因为我的数组包含 "Optionals"。
总结: 我如何根据 TableView 中的名称生成按字母顺序排列的部分 headers 使用一组未像上面 Swift 3 中给出的字典那样分组的字典?
提前致谢!!
您可以使用 Array 的 .sorted(by: )
方法来比较数组中的元素。
这会产生一个 sortedArray:
let sortedArray = arrayOfApps.sorted(by: {([=10=]["name"] as! String) <= (["name"] as! String)})
如果 itemName 不是字符串,这将崩溃,但我将其留给您处理任何错误。例如将其更改为:
[=11=]["name"] as? String ?? ""
编辑: // 删除示例并添加扩展以创建所需结果
我找到了我的一个旧项目,我在其中编写了这样的扩展。对它进行了一些更改以满足您的需要,请告诉我它是否还需要更改:
extension Array {
func sectionTitlesForArray(withName name: (Element) -> String) -> Array<(title: String, elements: NSMutableArray)> {
var sectionTitles = Array<(title: String, elements: NSMutableArray)>()
self.forEach({ element in
var appended = false
sectionTitles.forEach({ title, elements in
if title == name(element) {
elements.add(element)
appended = true
}
})
if appended == false {
sectionTitles.append((title: name(element), elements: [element]))
}
})
return sectionTitles
}
}
// Usage single letter as Section title:
let sectionTitles = arrayOfApps.sectionTitlesForArray(withName: {
let name = [=12=]["name"] as! String
return String(name[name.startIndex])
})
// Quick dirty pretty-print:
sectionTitles.forEach({ sectionTitle in
print("Section title: \(sectionTitle.title) \n")
sectionTitle.elements.forEach({ object in
let element = object as! Dictionary<String,Any>
print("Element name: \(element["name"]!)")
})
print("")
})