swift中数组模型字典的过滤数组

swift中数组模型字典的过滤数组,swift,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")]],

我有以下格式的数据

[["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中对给定的数据执行搜索&我编写了下面的代码

//标记:-搜索商户并重新加载表

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',我会得到错误的搜索结果

请说明我在搜索数据时做错了什么


如果我必须解释我的问题,请告诉我。

您的
searchByNamesArray
的问题是它将返回一个字典数组,在这种情况下,它是带有
“T”
键的。后者包含许多可能与您的搜索词不匹配的商家

以下是您应该如何做到这一点:

let merchants: [MerchantModel] = data
    .map {Array($0.values)}
    .flatMap{$0}
    .flatMap{$0}
    .filter {$0.nameString.contains("Tr")}
因此,当用户搜索
“Tr”
,结果将是
“Tread and Miller”


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

太宽了。你所说的
我在搜索栏中键入'Tr'是什么意思?我在搜索时出错了
?你是得到了错误的结果还是根本没有结果?更具体地说,您的数据中缺少
“D”
中的
squareImageUrlString
这个答案的问题是,提问者的函数应该“返回”一个
[[String:[MerchantModel]]]
,而不是
[MercantModel]
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()
}