94

我有一系列字典。

我想根据一个键过滤数组。

我试过这个:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(SPORT ==  %@)", @"Football"];

NSArray *filteredArray = [data filteredArrayUsingPredicate:predicate];

这不起作用,我没有得到任何结果。我想我做错了什么。如果“SPORT”是 ivar,我知道这就是方法。我认为如果它是一把钥匙,它可能会有所不同。

但是,我无法找到示例。

谢谢


更新

我在要搜索的字符串周围添加了引号。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(SPORT ==  '%@')", @"Football"];

它仍然不起作用。


更新 2

解决了。我实际上不得不删除单引号,这似乎与指南所说的背道而驰。

我真正的问题是我有一个嵌套数组,我实际上并没有评估字典。骨头动。

4

6 回答 6

151

它应该可以工作 - 只要数据变量实际上是一个包含带有键 SPORT 的字典的数组

NSArray *data = [NSArray arrayWithObject:[NSMutableDictionary dictionaryWithObject:@"foo" forKey:@"BAR"]];    
NSArray *filtered = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"(BAR == %@)", @"foo"]];

在这种情况下过滤包含字典。

( %@ 不必被引用,这是在 NSPredicate 创建对象时完成的。)

于 2009-06-06T00:18:57.500 回答
27

我知道这是旧消息,但要加上我的两分钱。默认情况下,我使用命令LIKE[cd]而不仅仅是[c]. 将[d]字母与重音符号进行比较。这在我的魔兽应用程序中特别有效,人们拼写他们的名字“Vòódòó”,几乎不可能在表格视图中搜索他们的名字。在[d]谓词中去掉它们的重音符号。@"name LIKE[CD] %@", object.name因此where的谓词object.name == @"voodoo"将返回包含名称 Vòódòó 的对象。

来自 Apple 文档:like[cd] 的意思是“不区分大小写和变音符号的 like”。)有关字符串语法的完整描述和所有可用运算符的列表,请参阅Predicate Format String Syntax

于 2012-08-26T17:05:24.587 回答
11
#import <Foundation/Foundation.h>
// clang -framework Foundation Siegfried.m 
    int
main() {
    NSArray *arr = @[
        @{@"1" : @"Fafner"},
        @{@"1" : @"Fasolt"}
    ];
    NSPredicate *p = [NSPredicate predicateWithFormat:
        @"SELF['1'] CONTAINS 'e'"];
    NSArray *res = [arr filteredArrayUsingPredicate:p];
    NSLog(@"Siegfried %@", res);
    return 0;
}
于 2013-08-01T19:09:44.393 回答
3

NSPredicate仅在 iPhone 3.0 中可用。

在尝试在设备上运行之前,您不会注意到这一点。

于 2009-06-06T12:23:22.713 回答
0

在 Swift 3 中,当您想要使用基于字典键和值的谓词过滤字典数组时,您可以选择以下模式之一。


#1。使用NSPredicate init(format:arguments:)初始化器

如果您来自 Objective-C,请init(format:arguments:)提供一种键值编码风格来评估您的谓词。

用法:

import Foundation

let array = [["key1": "value1", "key2": "value2"], ["key1": "value3"], ["key3": "value4"]]

let predicate = NSPredicate(format: "key1 == %@", "value1")
//let predicate = NSPredicate(format: "self['key1'] == %@", "value1") // also works
let filteredArray = array.filter(predicate.evaluate)

print(filteredArray) // prints: [["key2": "value2", "key1": "value1"]]

#2。使用NSPredicate init(block:)初始化器

作为替代方案,如果您更喜欢强类型API 而不是字符串类型API,则可以使用init(block:)初始化程序。

用法:

import Foundation

let array = [["key1": "value1", "key2": "value2"], ["key1": "value3"], ["key3": "value4"]]

let dictPredicate = NSPredicate(block: { (obj, _) in
    guard let dict = obj as? [String: String], let value = dict["key1"] else { return false }
    return value == "value1"
})

let filteredArray = array.filter(dictPredicate.evaluate)
print(filteredArray) // prints: [["key2": "value2", "key1": "value1"]]
于 2017-03-29T20:54:04.230 回答
-1

查看NSPredicate 参考,您似乎需要用引号将替换字符括起来。例如,您当前的谓词读取:(SPORT == Football)您希望它读取(SPORT == 'Football'),因此您的格式字符串需要是@"(SPORT == '%@')"

于 2009-06-06T00:13:15.907 回答