Swift / SwiftUI unique dictionary value

82 Views Asked by At

I'm having a challenge with generating a distinct list of variables from a dictionary received from an API.

The data received is an array of:

struct ContactDetails: Codable, Hashable, Identifiable {
    var id = UUID()
    var company, name, email, phone, mobile, city, region: String
}

I am displaying the data in a view as follows:

let results = ...array of the ContactDetails received
        if results != nil {
            List {
                ForEach(results ?? [], id: \.self) { result in
                    NavigationLink(destination: ProjectContactDetailsView(company: result.company, results: results ?? [])) {
                        Text(result.company)
                            .tag(result.id)
                    }
                }
            }
        }

In many instances I am receiving 30 to 40 of these results, and some are contacts from the same company. As you can see I am linking to a new view with more details based on the company name where I will list the individuals. How do I reduce or get a distinct list of the company names?

I have tried:

using an extension:

extension Sequence where Iterator.Element: Hashable {
    func unique() -> [Iterator.Element] {
        var seen: Set<Iterator.Element> = []
        return filter { seen.insert($0).inserted }
    }
}

But I can't get this sequencing correct:

ForEach(results ?? [], id: \.self) { result in
                   ForEach(result.company.unique()) { company in
                       NavigationLink(destination: ProjectContactDetailsView(company: result.company, results: results ?? [])) {
                           Text(result.company)
                               .tag(result.id)
                       }
                   }
               }

Any ideas?

1

There are 1 best solutions below

3
unhep On

Got it working as follows:

    struct ProjectContactSubContractorView: View {

    @EnvironmentObject var env: Env

    var body: some View {

        let results = env.project.response?.container?.project?.subcontractors?.contact

        if let results = results {

            let groupedByCompany = Dictionary(grouping: results, by: { $0.company })

            List {

                ForEach(groupedByCompany.keys.sorted(), id: \.self) { company in
                    NavigationLink(destination: ProjectContactDetailsView(company: company, results: groupedByCompany[company] ?? [])) {
                        Text(company)
                    }
                }

            }

        }

    }

}