Как я могу отфильтровать NSDictionary с UISearchBar? - PullRequest
0 голосов
/ 04 сентября 2018

Мне нужно изменить функцию поиска с фильтрации массива:

func filterContentForSearchText(searchText: String, scope: String = "All") {
    if searchText != "" {

        filteredName = CGCoins.shared.ids.filter {name in
            return   name.lowercased().contains(searchText.lowercased())}
    } else { filteredName = CGCoins.shared.ids

    }
}

для фильтрации словаря, который содержит символы и соответствующие им названия. В идеале я хочу иметь возможность искать и ключ, и значение, например, словарь (CGCoins.shared.coinDictionary) выглядит следующим образом:

["btc":"bitcoin","eth":"ethereum","ltc":"litecoin"...]

, поэтому я хочу иметь возможность выполнять поиск с помощью UISearchBar и иметь возможность выполнять поиск как «btc» и возвращать «биткойн», так и искать «биткойн», а также возвращать «биткойн».

Я пробовал это:

func filterNewForSearchText(searchText: String, scope: String = "All") {
    if searchText != "" {

        filteredName = CGCoins.shared.coinDictionary.filter {name in
            return   name.key == searchText}
    } else { filteredName = CGCoins.shared.coinDictionary.values

    }
}

но я получаю ошибку:

Невозможно присвоить значение типа '[String: String]' для типа '[String]'

Как я могу успешно отфильтровать словарь по ключу и значению и вернуть значение того, что ищется? Любые альтернативные решения также приветствуются.

Ответы [ 3 ]

0 голосов
/ 04 сентября 2018

Сообщение об ошибке происходит из-за того, что фильтрация словаря не возвращает его значения автоматически, но вам придется получить его ключей и затем обернуть их в массив:

Следующее ищет точное совпадение в ключах, или если searchText содержится в значениях:

if searchText != "" {
    filteredName = Array(CGCoins.shared.coinDictionary.filter {name in
        return name.key == searchText || name.value.lowercased().contains(searchText.lowercased())
        }.values)
} else {
    filteredName = Array(CGCoins.shared.coinDictionary.values)
}
0 голосов
/ 04 сентября 2018

Попробуйте, это работает

для запроса Like (строка содержит другую строку)

let data = ["btc":"bitcoin","eth":"ethereum","ltc":"litecoin"]

let filtered = data.filter { $0.key.contains("c") || $0.value.contains("c") }
print(filtered) // ["btc":"bitcoin","ltc":"litecoin"]

Для точного соответствия строки

let filtered = data.filter { $0.key == "btc"  || $0.value == "litecoin" }
0 голосов
/ 04 сентября 2018

Фильтрация словаря возвращает кортеж, необходимый для отображения результата и возврата значений словаря. В остальной части вам нужно создать новый массив из его значений:

func filterNewForSearchText(searchText: String, scope: String = "All") {
    if !searchText.isEmpty  {
        filteredName = CGCoins.shared.coinDictionary
                           .filter { 
                               $0.key == searchText 

                            // if you need to search key and value and include partial matches
                            // $0.key.contains(searchText) || $0.value.contains(searchText)

                            // if you need to search caseInsensitively key and value and include partial matches
                            // $0.key.range(of: searchText, options: .caseInsensitive) != nil || $0.value.range(of: searchText, options: .caseInsensitive) != nil
                            }
                           .map{ $0.value }
    } else {
        filteredName = Array(CGCoins.shared.coinDictionary.values)
    }
}
...