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

时间:2017-07-20 05:44:44

标签: ios arrays swift cocoa-touch filter

我是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(($0["name"] as! String).characters.prefix(strSeach.characters.count)).lowercased() == strSeach.lowercased()}

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

输出为:

  

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

但是混乱,这是正确的搜索方式吗?我使用characters.prefixlowercased()是好还是其他最佳方式?

如果我想通过“名称”,“年龄”等应用多次搜索,那么我们如何才能在 swift过滤器中实现?

我认为我们不能将NSPredicate与Swift Array一起使用?否则,我们可以通过以下方式来实现

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

就像那样!

4 个答案:

答案 0 :(得分:1)

使用过滤器

您可以使用此

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 { ($0["name"] as!    String).lowercased().contains(searchSting.lowercased()) }

输出

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

WITH Predicates

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

<强>输出

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

答案 1 :(得分:1)

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

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

此外,这是使用swift过滤器执行此操作的另一种方法:

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

答案 2 :(得分:1)

您应该使用模型值

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

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 { $0.name.lowercased().contains("k") }

结果

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

答案 3 :(得分:0)

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

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

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

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