从字典 [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("")
})