使用 NSPredicate 根据 属性 过滤对象的 NSArray,这是一个 NSDictionary

Using NSPredicate to filter an NSArray of objects based on a property which is an NSDictionary

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

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

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

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

我想根据 NSDictionarykeyOne 过滤我的虚拟对象的 NSArray,这是 Dummy 对象的 属性。

我该怎么做?我浏览了:

但是好像不适用。

您没有提供任何关于您正在使用的代码 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)

在Objective-C中:

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

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

给你,使用真实 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 { [=10=].dict["keyOne"] == "one" }

几点注意事项:

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