Reputation: 91
My JSON data file is already alphabetized and is properly showing in my TableView. I set up my section titles using:
struct FigureStats: Decodable {
let name: String
let number: String
let year: String?
}
var figSectionTitles = [String]()
var figures = [FigureStats]()
override func viewDidLoad() {
super.viewDidLoad()
figSectionTitles = [String](arrayLiteral: "#", "A", "B", "C")
}
func tableView( tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return figSectionTitles [section]
}
func tableView( tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return figures.count
}
func downloadJSON(completed: @escaping () -> ()) {
let url = URL(string: "https://xxxx")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error == nil {
do {
self.figures = try JSONDecoder().decode([FigureStats].self, from: data!)
DispatchQueue.main.async {
completed()
}
} catch {
print("JSON Error")
}
}
}.resume()
}
The problem is all of the entries are repeated inside each section instead of falling under the correct section based on the first character of each name.
How can get the first character of each name and then get those entries to fall under the correct section?
Upvotes: 1
Views: 2811
Reputation: 15748
You can use init(grouping:by:) to group the array into Dictionary.
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
var figures = [Employee]()
var figuresByLetter = [(key: String, value: [Employee])]()
override func viewDidLoad() {
super.viewDidLoad()
figures = [Employee(name: "Kofi", year: 2000, id: 1),Employee(name: "Abena", year: 2002, id: 2),Employee(name: "Efua", year: 2003, id: 3),Employee(name: "Kweku", year: 2003, id: 3),Employee(name: "Akosua", year: 2003, id: 3)]
figuresByLetter = Dictionary(grouping: figures, by: { String($0.name.trimmingCharacters(in: .whitespaces).first!) }).sorted(by: { $0.0 < $1.0 })
print(figuresByLetter)
}
func numberOfSections(in tableView: UITableView) -> Int {
return figuresByLetter.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return figuresByLetter[section].key
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return figuresByLetter[section].value.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .default, reuseIdentifier: "cell")
cell.textLabel?.text = figuresByLetter[indexPath.section].value[indexPath.row].name
return cell
}
}
struct Employee {
var name:String?
var year:Int?
var id:Int?
}
Data after grouping
[(key: "A", value: [Employee(name: "Abena", year: 2002, id: 2), Employee(name: "Akosua", year: 2003, id: 3)]),
(key: "E", value: [Employee(name: "Efua", year: 2003, id: 3)]),
(key: "K", value: [Employee(name: "Kofi", year: 2000, id: 1), Employee(name: "Kweku", year: 2003, id: 3)])]
Upvotes: 5
Reputation: 1062
func numberOfSections(in tableView: UITableView) -> Int {
return figuresByLetter.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let sectionTitle = figuresByLetter[indexPath.section]
return sectionTitle
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionTitle = figuresByLetter[indexPath.section]
//filteredArray = filter the array of figures based on current section value
return filteredArray.count
}
Upvotes: 0