Swift:按名称(字符串)按字母顺序将对象数组映射到新数组中的单独字母集合中

fad*_*fad 6 arrays ios swift

我创建了一个名为Contact的结构,它代表一个人类联系人,其中当前有一些数组.它们已按字母顺序排序,但是我想按名称属性按字母顺序对它们进行排序,这是一个字符串,但我不想将它们按顺序放在一个数组中,我想将这些对象拆分成不同的集合.与他们名字的第一个字母相对应.例如."A"包含2个对象,其中联系人姓名以A开头,"B"表示Bobby,Brad等名称等等.

let contactData:[Contact] = [
  Contact(id: 1, available: true, name: "Adam"),
  Contact(id: 2, available: true, name: "Adrian"),
  Contact(id: 3, available: true, name: "Balthazar"),
  Contact(id: 4, available: true, name: "Bobby")
]
Run Code Online (Sandbox Code Playgroud)

我想创造类似的东西

let sectionTitles = ["A", "B"]
let sortedContactData = [
  [
    Contact(name: "Adam"),
    Contact(name: "Adrian")
  ],
  [
     Contact(name:"Balthazar")
     Contact(name:"Bobby")
  ]         
]
Run Code Online (Sandbox Code Playgroud)

或类似的东西......

最终的结果是我想将它们显示在UITableView中,其中包含Sections中的字母和将对象转换为indexPath.rows,就像iPhone的原生联系人应用程序所做的那样.我实际上不确定这是否是实现这一结果的最理想方式,所以我欢迎对这个问题的任何挑战!

ant*_*014 6

let sortedContacts = contactData.sorted(by: { $0.name < $1.name }) // sort the Array first.
print(sortedContacts)

let groupedContacts = sortedContacts.reduce([[Contact]]()) {
    guard var last = $0.last else { return [[$1]] }
    var collection = $0
    if last.first!.name.characters.first == $1.name.characters.first {
        last += [$1]
        collection[collection.count - 1] = last
    } else {
        collection += [[$1]]
    }
    return collection
}
print(groupedContacts)
Run Code Online (Sandbox Code Playgroud)
  1. 对列表进行排序.O(nlogn),其中n是数组中的项目数(contactData).
  2. 用于reduce迭代列表中的每个联系人,然后将其添加到新组或最后一个.O(n),其中n是数组中的项数(sortedContacts).

如果您需要更好的打印信息,最好使Contact符合协议 CustomStringConvertible