快速过滤数组模型字典的数组

时间:2018-09-03 14:41:05

标签: swift

我有以下格式的数据

[["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 :(得分:1)

首先,数据格式(分别包含一个键-值对的字典数组)的效率非常低。包含所有[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()
}

答案 1 :(得分:0)

您的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