[英]Using NSPredicate to filter an NSArray based on NSDictionary keys
我有一系列字典。
我想基於密鑰過濾數組。
我試過這個:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(SPORT == %@)", @"Football"];
NSArray *filteredArray = [data filteredArrayUsingPredicate:predicate];
這不起作用,我沒有結果。 我想我做錯了什么。 我知道如果“SPORT”是一個ivar,這就是方法。 我認為如果它是關鍵的話可能會有所不同。
然而,我無法找到一個例子。
謝謝
更新
我在我正在搜索的字符串周圍添加了引號。
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(SPORT == '%@')", @"Football"];
它仍然無法正常工作。
更新2
解決了它。 我實際上不得不刪除單引號,這似乎與指南所說的相反。
我真正的問題是我有一個嵌套數組,我實際上並沒有評估字典。 骨頭移動。
它應該工作 - 只要數據變量實際上是一個包含關鍵字SPORT的字典的數組
NSArray *data = [NSArray arrayWithObject:[NSMutableDictionary dictionaryWithObject:@"foo" forKey:@"BAR"]];
NSArray *filtered = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"(BAR == %@)", @"foo"]];
在這種情況下過濾包含字典。
(%@不必引用,這是在NSPredicate創建對象時完成的。)
我知道這是舊聞,但加上我的兩分錢。 默認情況下,我使用命令LIKE[cd]
而不僅僅是[c]
。 [d]
將字母與重音符號進行比較。 這在我的魔獸應用程序中特別有效,人們將其名稱拼寫為“Vòódòó”,因此幾乎不可能在桌面視圖中搜索他們的名字。 [d]
在謂詞中去掉它們的重音符號。 因此, @"name LIKE[CD] %@", object.name
的謂詞@"name LIKE[CD] %@", object.name
,其中object.name == @"voodoo"
將返回包含名稱Vòódòó的對象。
從Apple文檔:像[cd]表示“case-和diacritic-insensitive like”。)有關字符串語法的完整描述和所有可用運算符的列表,請參閱謂詞格式字符串語法 。
#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;
}
NSPredicate
僅適用於iPhone 3.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"]]
查看NSPredicate參考 ,看起來您需要用引號括住替換字符。 例如,您當前的謂詞讀取: (SPORT == Football)
您希望它讀取(SPORT == 'Football')
,因此您的格式字符串需要為@"(SPORT == '%@')"
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.