web-dev-qa-db-ja.com

NSPredicateを使用して、NSDictionaryキーに基づいてNSArrayをフィルタリングする

辞書がたくさんあります。

キーに基づいて配列をフィルターします。

私はこれを試しました:

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

NSArray *filteredArray = [data filteredArrayUsingPredicate:predicate];

これは機能せず、結果は得られません。私は何か間違ったことをしていると思います。 「SPORT」がivarの場合、これがメソッドであることがわかります。キーである場合、おそらく異なると思います。

ただし、例を見つけることができませんでした。

ありがとう


更新

検索する文字列の周りに引用符を追加しました。

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

それでも機能しません。


更新2

それを解決しました。実際には、一重引用符を削除する必要がありましたが、これはガイドが述べていることに反するようです。

私の本当の問題は、ネストされた配列があり、実際に辞書を評価していなかったことです。骨頭が動く。

94
Corey Floyd

動作するはずです-データ変数が実際にキーSPORTを持つ辞書を含む配列である限り

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

この場合、フィルターには辞書が含まれます。

(%@は引用符で囲む必要はありません。これはNSPredicateがオブジェクトを作成するときに行われます。)

150
suraken

私はそれが古いニュースであることを知っていますが、私の2セントを追加します。デフォルトでは、LIKE[cd]ではなく[c]コマンドを使用します。 [d]は、文字とアクセント記号を比較します。これは特に、Warcraftアプリで名前が「Vòódòó」と綴られているため、TableViewで名前を検索することはほぼ不可能です。 [d]は、述語の間にアクセント記号を取り除きます。したがって、@"name LIKE[CD] %@", object.nameの述語は、object.name == @"voodoo"がVòódòóという名前を含むオブジェクトを返します。

Apple documentation:like [cd]は「大文字と小文字を区別しないlike」を意味します。)文字列構文の完全な説明と利用可能なすべての演算子のリストについては、- 述語フォーマット文字列構文 .

27
ChargedNeuron
#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でのみ利用可能です。

デバイスで実行しようとするまで気付かないでしょう。

3
Rod

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よりもstringly型付けされた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"]]
_
0
Imanou Petit