Фильтрующий массив, который содержит необязательный - SearchBar

немного оглянуться назад, чтобы вы поняли мою проблему. В настоящее время я кодирую приложение iOS для событий, на которых у меня есть файл GuestList CoreData, сохраненный на устройстве.

В viewDidLoad он будет извлекать объект coredata и помещать его в массив из [GuestDetails]

Теперь структура объекта Guestdetail выглядит следующим образом:

private(set) public var guestFirstName: String
private(set) public var guestLastName: String?
private(set) public var guestEmail: String?
private(set) public var guestPhone: String?
private(set) public var guestUUID: UUID
private(set) public var guestBarcode: String?
private(set) public var guestCheckedIn: Bool

Это означает, что только первое имя, UUID и checkinStatus являются обязательными. Я уже настроил добавление JSON, но теперь моя проблема связана с моим GuestListViewController, у меня есть поисковая панель

Я использую следующий код и массив, чтобы убедиться, что я могу фильтровать. У меня есть еще один массив, который называется

searchResultArray = [GuestDetails]()

. Поэтому по существу я бы скопировал все данные моего гостя в searchResultArray, и это тот, с которого tableView получает свои источники.

Теперь как часть поиска, я использовал этот код, который я нашел на appcoda

searchResultArray = guestData.filter({guestData -> Bool in
   (guestData.guestFirstName.lowercased().contains(searchText.lowercased())) || 
   (guestData.guestLastName?.lowercased().contains(searchText.lowercased()))! ||
   (guestData.guestBarcode?.contains(searchText))!
})

. Проблема в том, что мое приложение терпит крах, если я только ищу по имени, он не будет сбой, так как они будут развернуты силой красиво, но если я добавлю код для поиска lastName или штрих-кода, он сработает. Я понимаю, что это, вероятно, из-за явного разворота, но xcode не позволит мне НЕ разворачивать его.

Я пробовал использовать карту (что не помогает, если только я недостаточно знаком с ней), у меня есть попробовал .compact (но я не мог заставить его работать, так как я не уверен, как он может получить доступ к внутренней части объекта GuestDetail для удаления nils). Проблема в том, что массив из [GuestDetails] сам не будет содержать нужных деталей внутри GuestDetails объект может, следовательно, вызвать его сбой.

Мой вопрос: как мне получить его для поиска по первому (уже возможно), последнему и штрих-коду?

Спасибо, и я надеюсь, что вопрос был достаточно сложным.

0
задан Kelvin Chong 13 August 2018 в 11:31
поделиться

1 ответ

Это интересная небольшая проблема, поэтому давайте ее обобщить. Вот наши тестовые данные, сопоставимые с вашим массивом GuestDetails:

struct S {
    var s1 : String
    var s2 : String?
    var s3 : String?
}

var array = [S]()
array.append(S(s1: "test", s2: "yo", s3: "ha"))
array.append(S(s1: "test", s2: nil, s3: nil))
array.append(S(s1: "Howdy", s2: "Bonjour", s3: "Hello"))

let target = "hello"

Некоторые свойства S являются необязательными, другие - нет.

Таким образом, проблема заключается в следующем: Filter array down to только те элементы, где любое свойство S содержит нашу строку target, используя сравнение без учета регистра.

Мы можем сделать это в одном утверждении:

let filteredArray = array.filter {
    [$0.s1,$0.s2,$0.s3].compactMap {$0}
        .map {$0.localizedCaseInsensitiveContains(target)}
        .contains(true)
}

Это не так эффективно, как что написал @Ladislav, потому что мы продолжаем цикл внутри map даже после того, как мы нашли нашу строку. Но неэффективность, вероятно, невелика.

2
ответ дан matt 15 August 2018 в 14:03
поделиться

Другие вопросы по тегам:

Похожие вопросы: