Princess
Princess

Reputation: 319

Assign keys and values from [(key: String, value: [[String : Any]])] in UITableView

I have an array of dictionaries, [[String:AnyObject]], which is reduce+sorted as below successfully.

 var arrUserList = [(key: String, value: [[String : Any]])]()


 let result = self.arrJsonDict.reduce(into: [String: [[String:Any]]]()) { result, element in
                    let strName: String = (element as! NSDictionary).value(forKey: "name") as! String
                    if let firstLetter = strName.first {
                        let initial = String(describing: firstLetter).uppercased()
                        result[initial, default: [[String:Any]]() ].append(element as! [String : Any])
                    }}.sorted { return $0.key < $1.key }


     self.arrUserList = result

Now I wanted to assign keys to table sections and values as table cell text from the array.

Upvotes: 0

Views: 354

Answers (1)

vadian
vadian

Reputation: 285082

This is very cumbersome code.

You are highly encouraged to use a struct rather than a dictionary at least with a member name

struct Person {
    let name : String
} 

Declare and rename arrJsonDic (more descriptively) as

var people : [Person]()

and arrUserList as

var users = [String: [Person]]()

For the sections declare another array

var letters = [String]()

Group the array and populate letters simply with

users = Dictionary(grouping: people, by: { String($0.name.first!) })
letters = users.keys.sorted()

In the table view in numberOfSections return

return letters.count

and in numberOfRows return

let letter = letters[section]
return users[letter]!.count

In cellForRowAt assign a name to a label with

let letter = letters[indexPath.section]
let user = users[letter]![indexPath.row]
cell.nameLabel.text = user.name

------------------------------

To make it still swiftier declare a second struct Section

struct Section {
    let index : String
    let people : [Person]
}

delete

var letters = [String]()

and declare users

var users = [Section]()

The grouping is slightly different

let grouped = Dictionary(grouping: people, by: { String($0.name.first!) })
users = grouped.map({ Section(index: $0.0, people: $0.1) }).sorted{$0.index < $1.index}

The code in the three table view delegate methods are

return users.count

-

return users[section].people.count

-

let user = users[indexPath.section].people[indexPath.row]
cell.nameLabel.text = user.name

Upvotes: 4

Related Questions