Фильтровать массив словаря модели массива в swift - PullRequest
0 голосов
/ 03 сентября 2018

У меня есть данные в формате ниже

[["B": [MerchantModel(idString: 90046, squareImageUrlString: "https:images/2017-06-30_093600_1498815360_21897", rectangleImageUrlString: "https:/2017-06-30_093613_1498815373_26005", nameString: "Burger", stateDescriptionString: "Active")]], ["C": [MerchantModel(idString: 9000014, squareImageUrlString: "https:/2017-01-24_122206_1485260526_19795", rectangleImageUrlString: "https://017-01-24_122225_1485260545_43345", nameString: "Cape Union Mart", stateDescriptionString: "Active")]], ["D": [MerchantModel(idString: 9000021, squareImageUrlString: "https:/2016-09-23_132804_1474637284_33036", rectangleImageUrlString: "https://2016-09-23_132733_1474637253_16434", nameString: "Dis-Chem", stateDescriptionString: "Active")]], ["O": [MerchantModel(idString: 9000015, squareImageUrlString: "_46238", rectangleImageUrlString: "https://2017-03-03_114409_1488541449_86767", nameString: "Old Khaki", stateDescriptionString: "Active"), MerchantModel(idString: 9001108, squareImageUrlString: "https://2015-12-08_074852_1449560932_14101", rectangleImageUrlString: "https:/2015-12-08_074924_1449560964_32669", nameString: "Outdoor Warehouse", stateDescriptionString: "Active")]], ["P": [MerchantModel(idString: 9000020, squareImageUrlString: "https://latform.images/2017-10-20_070751_1508483271_24232", rectangleImageUrlString: "https://s3-eu-west-1.ws.com/2017-10-20_070802_1508483282_60598", nameString: "Primi", stateDescriptionString: "Active")]], ["S": [MerchantModel(idString: 9001078, squareImageUrlString: "https/2015-05-26_131716_1432646236_31314", rectangleImageUrlString: "https://s3-eu-west-1.amazonaws.com/co.wigroup.global.wiplatform.images/2015-05-26_131726_1432646246_38768", nameString: "Steers", stateDescriptionString: "Active"), MerchantModel(idString: 9001102, squareImageUrlString: "https://s3-eu-west-1.amazonaws.com/co.wigroup.global.wiplatform.images/2015-11-04_102848_1446632928_54414", rectangleImageUrlString: "https://s3-eu-west-1.amazonaws.com/co.wigroup.global.wiplatform.images/2015-11-04_102909_1446632949_10764", nameString: "Sportsmans Warehouse", stateDescriptionString: "Active")]], ["T": [MerchantModel(idString: 9000051, squareImageUrlString: "https://s3-eu-west-1.amazonaws.com/co.wigroup.global.wiplatform.images/2017-02-27_122839_1488198519_16635", rectangleImageUrlString: "https://s3-eu-west-1.amazonaws.com/co.wigroup.global.wiplatform.images/2017-02-27_122858_1488198538_28922", nameString: "Tread and Miller", stateDescriptionString: "Active"), MerchantModel(idString: 9001132, squareImageUrlString: "https://s3-eu-west-1.amazonaws.com/co.wigroup.global.wiplatform.images/2016-10-25_112853_1477394933_57183", rectangleImageUrlString: "2016-10-25_112909_1477394949_90719", nameString: "Total", stateDescriptionString: "Active"), MerchantModel(idString: 9001168, squareImageUrlString: "/2017-05-02_133525_1493732125_25733", rectangleImageUrlString: "2017-05-02_133546_1493732146_85357", nameString: "Toys R Us", stateDescriptionString: "Active"), MerchantModel(idString: 9001170, squareImageUrlString: "2017-05-11_090202_1494493322_33697", rectangleImageUrlString: "2017-05-11_090539_1494493539_29021", nameString: "Toy Kingdom", stateDescriptionString: "Active")]]]

Где MerchantModel - класс модели, как показано ниже

struct MerchantModel {
    let idString : UInt
    var squareImageUrlString : String
    let rectangleImageUrlString : String
    let nameString : String
    let stateDescriptionString : String

}

Я должен выполнить поиск по заданным данным в UISearchbar, и я написал ниже код

// MARK: - поиск продавцов и таблица перезагрузки

func filter(array : [[String : [MerchantModel]]], byString filterString : String) {
    let searchByNamesArray = array.filter { $0.values.contains { $0.contains { $0.nameString.lowercased().contains(filterString.lowercased())} } }
    //Assign searched array into arrayOfMerchants
    self.arrayOfMerchants = searchByNamesArray
    //Reload table with new Data
    self.merchantTableView.reloadData()
}

выше метод поиска работает хорошо для немногих случаев, скажем «Bu» в строке поиска с возвращением «Burger», но если я наберу «Tr» в строке поиска, я получаю неправильный поиск

Пожалуйста, подскажите, что я делаю не так при поиске данных.

Пожалуйста, дайте мне знать, если я должен объяснить свой вопрос.

Ответы [ 2 ]

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

Прежде всего, формат данных (массив словарей, содержащий одну пару ключ-значение соответственно) очень неэффективен. Один словарь, содержащий все [String:[MerchantModel]], или один массив, содержащий все MerchantModel элементы, гораздо эффективнее.

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

func filter(array : [[String : [MerchantModel]]], byString filterString : String) {

    var searchByNamesArray = [MerchantModel]()
    if let firstChar = filterString.first {
        let prefix = String(firstChar)
        if let modelDictionary = array.first(where: { $0[prefix] != nil }) {
            searchByNamesArray = modelDictionary[prefix]!.filter({$0.nameString.range(of: filterString, options:[.caseInsensitive, .diacriticInsensitive]) != nil })
        } 
    }

    //Assign searched array into arrayOfMerchants
    self.arrayOfMerchants = searchByNamesArray

    //Reload table with new Data
    self.merchantTableView.reloadData()
}
0 голосов
/ 03 сентября 2018

Проблема с вашим searchByNamesArray состоит в том, что он возвращает массив словарей, и в этом случае это тот, у которого есть ключ "T". Последний содержит много продавцов, которые могут не соответствовать вашему запросу.

Вот как вы должны это сделать:

let merchants: [MerchantModel] = data
    .map {Array($0.values)}
    .flatMap{$0}
    .flatMap{$0}
    .filter {$0.nameString.contains("Tr")}

Таким образом, когда пользователь ищет "Tr", результат будет "Tread and Miller":

let merchants: [MerchantModel] = data.map {Array($0.values)}.flatMap{$0}.flatMap{$0}.filter {$0.nameString.contains("Tr")}
merchants.forEach {print($0.nameString)} //Tread and Miller
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...