atalayasa
atalayasa

Reputation: 3490

Filter dictionary of array objects

I am trying to filter my dictionary according to user input in UISearchController. I have following model and array of objects.

struct People {
    var name: String
    var id: Int
}
let first = People(name: "Atalay", id: 1)
let second = People(name: "Ahmet", id: 2)
let third = People(name: "Mehmet", id: 3)
let fourth = People(name: "Yusuf", id: 4)
let peoples: [People] = [first, second, third, fourth, fifth]

I put them into a dictionary to create section indexed table view with following code.

var dict: [String: [People]] = Dictionary(grouping: peoples, by: { (people) -> String in
    return String(people.name.prefix(1))
})

Above code gives me a dictionary with first letter of People names. Now, I would like to filter my array according to user input. However, I tried following code for filtering but it is not working as I expected.

let filteredDict = (dict.filter { $0.1.contains { $0.name.lowercased().contains("ata") } })

It returns all "A" letter section indexes like ["A": People(name: "Atalay", id: 1), People(name: "Ahmet", id: 2)] How can I achieve filter also my array inside dictionary?

Upvotes: 1

Views: 168

Answers (3)

nayem
nayem

Reputation: 7605

If I'm not mistaken, you want your final dictionary to have all the keys and only the filtered array of items as the values. If that is right, reduce is the tool for that:

let filtered = dict.reduce(into: [String: [People]]()) {
    $0[$1.key] = $1.value.filter { $0.name.lowercased().contains("ata") }
}

Upvotes: 1

Joakim Danielson
Joakim Danielson

Reputation: 52108

I decided it was simplest to get this right by using an old fashioned for loop and filter each group separately

var filtered = [String: [People]]()

for (k, v) in dict {
    let result = v.filter {$0.name.lowercased().contains("ata")}
    if result.count > 0 {
        filtered[k] = result
    } 
}

Note that if you want to keep all the groups in the result dictionary just skip the if result.count > 0 condition

Upvotes: 0

Savca Marin
Savca Marin

Reputation: 437

How can I achieve filter also my array inside dictionary?

You should have an array first, you can use flatMap to group all the values in your filteredDict

let array = filteredDict.flatMap { $0.value }

Then you just filter the array as usually

let filteredArray = array.filter { $0.name.lowercased().contains("ata") }

Upvotes: 0

Related Questions