【问题标题】:Using NSPredicate to filter an NSArray of objects based on a property which is an NSDictionary使用 NSPredicate 根据一个 NSDictionary 的属性过滤一个对象的 NSArray
【发布时间】:2015-11-16 15:53:36
【问题描述】:

我有一个具有以下属性的 NSArray 对象

@objc class Dummy: NSObject {
    let propertyOne: Int
    let propertyTwo: Int
    let propertyThree: NSDictionary
}

propertyThree中会有一定的键值对比如

keyOne => valueOne
keyTwo => valueTwo
keyThree => valueThree

我想根据NSDictionarykeyOne 过滤我的NSArray of Dummy Objects,这是Dummy 对象的一个​​属性。

我该怎么做呢?我看过了:

但它似乎不适用。

【问题讨论】:

  • 在您的阵列上使用filter 方法怎么样?您只需要提供一个闭包,它会为某个元素返回 true 或 false。

标签: ios swift nspredicate


【解决方案1】:

你没有提供任何关于你使用NSPredicate的代码,所以我写了一个简单的例子。也许这会对你有所帮助。

@objc class Dummy: NSObject {
    let propertyOne: Int = 1
    let propertyTwo: Int = 1
    let propertyThree: NSDictionary

    init(dict: NSDictionary) {
        propertyThree = dict
        super.init()
    }
}

let arr: NSArray = [
    Dummy(dict: ["keyOne" : "one"]),
    Dummy(dict: ["keyOne" : "two"]),
    Dummy(dict: ["keyOne" : "three"]),
    Dummy(dict: ["keyOne" : "one"]),
    Dummy(dict: ["keyOne" : "five"])
]

let predicate = NSPredicate(format: "SELF.propertyThree.keyOne == 'one'")
let results = arr.filteredArrayUsingPredicate(predicate)
print(results)

【讨论】:

  • 通过谓词获取字典键值的其他可能语法是self.propertyThree[\"keyOne\"]
  • @Bannings,考虑到这个问题,如果我想过滤“int”变量,那我该怎么办?
  • @Vats 会是这样的:let predicate = NSPredicate(format: "SELF.propertyOne == 1")
【解决方案2】:

在 Objective-C 中:

[array filteredArrayUsingPredicate:[NSPredicate 
                         predicateWithFormat:@"propertyThree.keyOne = %@", value]];

在 Swift 中,您可以使用它的改编版,但正如 Kametrixom 建议的那样,使用 filter 和闭包会更正常;这就是删除动态键值编码步骤的机制。

【讨论】:

  • 我想有错字.keyOne = %@一定是.keyOne == %@。我说得对吗,@Tommy?
【解决方案3】:

给你,使用真正的 Swift:

class Dummy {
    let propertyOne: Int = 1
    let dict: [String : String]

    init(dict: [String : String]) {
        self.dict = dict
    }
}

let arr = [
    Dummy(dict: ["keyOne" : "one"]),
    Dummy(dict: ["keyOne" : "two"]),
    Dummy(dict: ["keyOne" : "three"]),
    Dummy(dict: ["keyOne" : "one"]),
    Dummy(dict: ["keyOne" : "five"])
]

let result = arr.filter { $0.dict["keyOne"] == "one" }

几点说明:

  • 在 Swift 中你不需要你的类从 NSObject 继承,如果他们这样做了,@objc 属性无论如何都会被隐式应用
  • 使用[NSObject : AnyObject] 而不是NSDictionary,因为它是等效的。我在这里使用了[String : String],因为它显然是这样的
  • 使用filter 方法,您可以以类型安全的方式过滤您的数组,而且速度更快

【讨论】:

    猜你喜欢
    • 2012-05-17
    • 2010-10-31
    • 2013-11-20
    • 2012-08-02
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    相关资源
    最近更新 更多