Как мне отфильтровать весь объект в панели поиска - PullRequest
0 голосов
/ 15 октября 2019

В моем Xcode проекте у меня есть tableView с list данными. Я реализовал searchBar для фильтрации ввода пользователя. Я бы хотел, чтобы он фильтровал весь мой объект var contactArray = [ExternalAppContactsBook](), но по какой-то причине мне разрешено фильтровать только его свойства, например contactArray.firstName. Вот как это выглядит в searchbar функции:

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {        
    if searchBar.text?.count == 0 {
        isFiltered = false
    }else {
        print("HELLO")
        isFiltered = true

        filteredName = contactArray.filter({$0.firstName.lowercased().prefix(searchText.count) == searchText})
    }
    tableViewOutlet.reloadData()
}

Итак, вместо $0.firstName я хотел бы получить $0.prefix, но компилятор говорит, что такого свойства нет.

С помощью $0.firstName я могу искать только имена в списке, что довольно ограничивает ... Я поступаю об этом правильно или что мне делать?

Редактировать ExternalAppContactsBook выглядит следующим образом:

class ExternalAppContactsBook {

var firstName = ""
var lastName = ""
var phoneNumber = ""
var company = ""
}

Я переписал свой код, но столкнулся с той же проблемой. Это то, что у меня сейчас есть в searchBar textDidChange:

filteredName = contactArray.filter({ object -> Bool in
    guard let text = searchBar.text else {return false}
    return object.firstName.contains(text)
})

Это работает, но работает только тогда, когда я ищу по имени человека в списке. Я также хочу иметь возможность искать их фамилии.

Поэтому я попытался добавить еще одну:

filteredLastName = contactArray.filter({ object -> Bool in
    guard let text = searchBar.text else {return false}
    return object.lastName.contains(text)
})

Затем в cellForRowAt _

 if isFiltered {
        contactName = filteredName[indexPath.row].firstName
        contactLastName = filteredLastName[indexPath.row].lastName
 ...}

Но это, очевидно, не работает и создает проблему с тем, сколько rows должно быть возвращено в numberOfRowsInSection

1 Ответ

1 голос
/ 15 октября 2019

Вы можете просто использовать условие с OR (||) при фильтрации

let filteredName = contactArray.filter {$0.firstName.starts(with: searchStr) || $0.lastName.starts(with: searchStr)}

Вы также можете добавить это как функцию в свой класс

func isMatch(_ searchString: String) -> Bool {
    return firstName.starts(with: searchString) || lastName.starts(with: searchString)
}

И затем фильтровать

let filteredName = contactArray.filter {$0.isMatch(searchStr)}
...