0

Let's say you have an array of Car structs, which incorporates an array of previous owners.

struct Car {
   var model: String // Ford Taurus
   var owners: [Owner]
}

struct Owner {
   var name: String // Harrison Ford
   var location: String // Oxford
}

When people search for "Ford" I want to check the Car model as well as the Owner name and location for the word 'ford'. I know how to filter the Car model, but not the Owner properties.

let filteredCars = cars.filter { (car) -> Bool in
            return car.model.lowercased().contains(textToSearch.lowercased())
        }

How do I filter the owner properties as well?

3 Answers 3

2

Do a double filter with or, for the owner I joined both properties before searching since it doesn't matter which one that matches

let searchKey = "Ford".lowercased()
let selected = cars.filter({
    $0.model.lowercased().contains(searchKey) ||
    $0.owners.contains(where: {"\($0.name) ($0.location)".lowercased().contains(searchKey)})})
Sign up to request clarification or add additional context in comments.

Comments

1

You need

let filteredCars = cars.filter {
    return $0.model.lowercased().contains(textToSearch.lowercased()) ||
           !$0.owners.filter { $0.name.lowercased().contains(textToSearch.lowercased())}.isEmpty

}

Comments

1

First of all two conversions to lowercase per iteration is not very efficient.

Better use range(of with option .caseInsensitive.

let filteredCars = cars.filter { (car) -> Bool in
    return car.model.range(of: textToSearch, options: .caseInsensitive) != nil ||
    !car.owners.filter({"\($0.name) \($0.location)".range(of: textToSearch, options: .caseInsensitive) != nil}).isEmpty
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.