我有一系列词典。
我想根据键过滤数组。
我试过了:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(SPORT == %@)", @"Football"];
NSArray *filteredArray = [data filteredArrayUsingPredicate:predicate];
这不起作用,我没有结果。我想我做错了什么。我知道如果“SPORT”是一个ivar,这就是方法。我认为如果它是一把钥匙可能会有所不同。
然而,我无法找到一个例子。
由于
更新
我在我正在搜索的字符串周围添加了引号。
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(SPORT == '%@')", @"Football"];
它仍然不起作用。
更新2
解决了它。我实际上不得不删除单引号,这似乎与指南所说的相反。
我真正的问题是我有一个嵌套数组,而我实际上并没有评估字典。骨头移动。
答案 0 :(得分:150)
它应该可以工作 - 只要数据变量实际上是一个包含关键字SPORT
的字典的数组NSArray *data = [NSArray arrayWithObject:[NSMutableDictionary dictionaryWithObject:@"foo" forKey:@"BAR"]];
NSArray *filtered = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"(BAR == %@)", @"foo"]];
在这种情况下过滤包含字典。
(%@不必引用,这是在NSPredicate创建对象时完成的。)
答案 1 :(得分:27)
我知道这是旧闻,但要加我的两分钱。默认情况下,我使用命令LIKE[cd]
而不仅仅是[c]
。 [d]
将字母与重音符号进行比较。这在我的魔兽应用程序中特别有效,人们将其名称拼写为“Vòódòó”,因此几乎不可能在桌面视图中搜索他们的名字。 [d]
在谓词期间删除其重音符号。所以@"name LIKE[CD] %@", object.name
的谓词,其中object.name == @"voodoo"
将返回包含名称Vòódòó的对象。
来自Apple文档: 像[cd]表示“case-and diacritic-insensitive like。”。有关字符串语法的完整描述以及所有可用运算符的列表,请参阅Predicate Format String Syntax。
答案 2 :(得分: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;
}
答案 3 :(得分:3)
NSPredicate
仅适用于iPhone 3.0。
在尝试在设备上运行之前,您不会注意到这一点。
答案 4 :(得分:0)
使用Swift 3时,如果要使用基于字典键和值的谓词过滤字典数组,可以选择以下模式之一。
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"]]
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"]]
答案 5 :(得分:-1)
查看NSPredicate reference,看起来您需要用引号括住替换字符。例如,您当前的谓词为:(SPORT == Football)
您希望它读取(SPORT == 'Football')
,因此您的格式字符串必须为@"(SPORT == '%@')"
。