簡體   English   中英

使用NSPredicate根據NSDictionary鍵過濾NSArray

[英]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時,如果要使用基於字典鍵和值的謂詞過濾字典數組,可以選擇以下模式之一。


#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"]]

查看NSPredicate參考 ,看起來您需要用引號括替換字符。 例如,您當前的謂詞讀取: (SPORT == Football)您希望它讀取(SPORT == 'Football') ,因此您的格式字符串需要為@"(SPORT == '%@')"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM