user11345388
user11345388

Reputation:

How to group friends by the first letter of the last name in UItableView into sections

I have friend struct model.

struct Friend {
    let name: String
    let photoImageName: String
}

And my FriendsViewController with tableview outlet

final class FriendsViewController: UIViewController {
    // MARK: - IBOutlet

    @IBOutlet var tableView: UITableView!
    
    // MARK: - Private Properties

    private var friendsArray = [
        Friend(name: "Donald Trump", photoImageName: "donald"),
        Friend(name: "Mister Alan", photoImageName: "alan"),
        Friend(name: "Eric Cartman", photoImageName: "cartman"),
        Friend(name: "Tom Cruze", photoImageName: "cruze"),
    ]

    // MARK: - Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        configureTable()
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "GoToDetailPhoto" {
            guard let destVC = segue.destination as? DetailPhotoCollectionViewController else { return }
            if let indexPath = tableView.indexPathForSelectedRow {
                let imageToTransfer = friendsArray[indexPath.row].photoImageName
                destVC.imageName = imageToTransfer
            }
        }
    }

    // MARK: - Private methods

    private func configureTable() {
        tableView.dataSource = self
        friendsArray.sort { $0.name < $1.name }
    }
}

// MARK: - Table view data source

extension FriendsViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        friendsArray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(
            withIdentifier: FriendViewCell.identifier,
            for: indexPath
        ) as? FriendViewCell else { return UITableViewCell() }
        cell.configure(friend: friendsArray[indexPath.row])
        return cell
    }
}

How to separate them into different sections by first letter of lastname. Like in contacts app. Thank you for you answers. I think about dictionary with character but cant write it correctly

Upvotes: 0

Views: 218

Answers (2)

user11345388
user11345388

Reputation:

Changed array to two demensional array :

private var friendsArray = [
        [Friend(name: "Donald Trump", photoImageName: "donald")],
        [Friend(name: "Mister Alan", photoImageName: "alan")],
        [Friend(name: "Eric Cartman", photoImageName: "cartman"),
        Friend(name: "Tom Cruze", photoImageName: "cruze")],
    ]

func numberOfSections(in tableView: UITableView) -> Int {
        filteredArrayOfGroups.count
    }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        filteredArrayOfGroups[section].count
    }

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let label = UILabel()
        label.text = friendsArray[section][0].name.first?.description ?? ""
        label.backgroundColor = UIColor.white.withAlphaComponent(0.5)
        return label
    }

Upvotes: 0

Paul Peelen
Paul Peelen

Reputation: 10329

In your question, to get a list of unique surname/lastname listing, you can accomplish this with the following:

let photoNameLetters = Set(friendsArray.map({ $0.photoImageName[$0.photoImageName.startIndex] }))

let lastNameLetters: Set<String> = Set(friendsArray.compactMap({
    guard let lastName = $0.name.components(separatedBy: .whitespaces).last else { return nil }
    return String(lastName[lastName.startIndex].lowercased())
}))

That should do the trick. However, it'll only look as the last word in the "name" property. People can have surnames with spaces. E.g. "Van der Wiel" or "Wiel, van der".

Upvotes: 0

Related Questions