从字典数组中搜索结果的最佳方法

Best way to search result from array of dictionary

我是 Swift 语言的新手,所以正在玩 Playground。

正如我的标题所说,从字典数组中搜索结果的最佳方法是什么?

例如

下面是我为学习目的创建的数组。

let array = [
    ["name": "Amit", "age": "27", "rollno": 12],
    ["name": "Ananad", "age": "26", "rollno": 10],
    ["name": "Kashyap", "age": "25", "rollno": 11],
    ["name": "Raj", "age": "25", "rollno": 07],
    ["name": "Akshya", "age": "28", "rollno": 13]
]

我想根据用户输入搜索 "name"。看看下面我做了什么。

let strSeach = "k"
let searchResult = myArray.filter{String(([=11=]["name"] as! String).characters.prefix(strSeach.characters.count)).lowercased() == strSeach.lowercased()}

print("index => \(searchResult)")

输出为:

searchResult => [["rollno": 11, "name": "Kashyap", "age": "25"]]

但是迷茫,这样的搜索方式对吗?我用了 characters.prefix, lowercased() 这样好还是其他最好的方法?

并且如果我想应用多个搜索,例如 "name"、"age" 等搜索,那么我们如何在 swift 过滤器中实现它?

我认为我们不能将 NSPredicate 与 Swift Array 一起使用?否则,我们可以按照

let searchPredicate = NSPredicate(format: "name CONTAINS [c] %@ OR age CONTAINS [c]", strSeach)

就像那样!

您可以在过滤器中使用 contains 关键字,如下所示,

let searchResult = myArray.filter{String(([=10=]["name"] as! String).lowercased().contains(strSeach.lowercased())}

对于多个过滤器(我正在根据您的谓词添加条件),

let searchResult = myArray.filter{(String(([=11=]["name"] as! String).lowercased().contains(strSeach.lowercased())) || (String(([=11=]["age"] as! String).lowercased().contains(strSeach.lowercased()))}

有过滤器

你可以使用这个

let array = [
["name": "Amit", "age": "27", "rollno": 12],
["name": "Ananad", "age": "26", "rollno": 10],
["name": "Kashyap", "age": "25", "rollno": 11],
["name": "Raj", "age": "25", "rollno": 07],
["name": "Akshya", "age": "28", "rollno": 13]
]

let searchSting = "am"

var search = array.filter { ([=10=]["name"] as!    String).lowercased().contains(searchSting.lowercased()) }

输出

[["rollno": 12, "name": "Amit", "age": "27"]]

带谓词

let searchPredicate = NSPredicate(format: "name CONTAINS [c] %@ OR age == %@", searchSting)
search = array.filter { searchPredicate.evaluate(with: [=12=])}

输出

[["rollno": 12, "name": "Amit", "age": "27"]]

您可以根据需要使用 NSPredicate,但请注意它比 filter 慢。

您只需将 swift 数组转换为 NSArray,然后调用 filtered.

此外,还有另一种使用 swift 过滤器的方法:

let searchResult = array.filter { 
    ([=10=]["name"] as! String).lowercased().hasPrefix(strSeach.lowercased()) }

您应该使用模型值

首先您应该定义以下模型值来表示您的数据

struct Person {

    let name: String
    let age: Int
    let rollno: Int

    init?(dict:[String:Any]) {
        guard
            let name = dict["name"] as? String,
            let ageText = dict["age"] as? String,
            let age = Int(ageText),
            let rollno = dict["rollno"] as? Int
            else { return nil}

        self.name = name
        self.age = age
        self.rollno = rollno
    }
}

现在,给定您的初始数组

let data = [
    ["name": "Amit", "age": "27", "rollno": 12],
    ["name": "Ananad", "age": "26", "rollno": 10],
    ["name": "Kashyap", "age": "25", "rollno": 11],
    ["name": "Raj", "age": "25", "rollno": 07],
    ["name": "Akshya", "age": "28", "rollno": 13]
]

你可以得到一个Person(s)

的数组
let persons = data.flatMap(Person.init)

名字中包含字符串的人

现在过滤部分是微不足道的,看

let personsWhereNameContainsK = persons.filter { [=13=].name.lowercased().contains("k") }

结果

[
    Person(name: "Kashyap", age: 25, rollno: 11),
    Person(name: "Akshya", age: 28, rollno: 13)
]