回答:
NSArray
及びNSMutableArray
フィルタアレイの内容に方法を提供します。指定された述語と一致するレシーバー内のオブジェクトを含む新しい配列を返すfilteredArrayUsingPredicateをNSArray
提供します。filterUsingPredicate:を追加します。これは、指定された述語に対してレシーバーのコンテンツを評価し、一致するオブジェクトのみを残します。これらのメソッドを次の例に示します。NSMutableArray
NSMutableArray *array =
[NSMutableArray arrayWithObjects:@"Bill", @"Ben", @"Chris", @"Melissa", nil];
NSPredicate *bPredicate =
[NSPredicate predicateWithFormat:@"SELF beginswith[c] 'b'"];
NSArray *beginWithB =
[array filteredArrayUsingPredicate:bPredicate];
// beginWithB contains { @"Bill", @"Ben" }.
NSPredicate *sPredicate =
[NSPredicate predicateWithFormat:@"SELF contains[c] 's'"];
[array filteredArrayUsingPredicate:sPredicate];
// array now contains { @"Chris", @"Melissa" }
これを行う方法はたくさんありますが、最も近いものは確かに次のものを使用してい[NSPredicate predicateWithBlock:]
ます:
NSArray *filteredArray = [array filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) {
return [object shouldIKeepYou]; // Return YES for each object you want in filteredArray.
}]];
それは、できるだけ簡潔なものだと思います。
NSArray
Swift でsを使用する人にとっては、これをさらに簡潔なバージョンにすることをお勧めします。
nsArray = nsArray.filter { $0.shouldIKeepYou() }
filter
は単なるメソッドですArray
(NSArray
暗黙的にSwiftにブリッジされArray
ます)。引数は1つBool
です。配列内の1つのオブジェクトを取り、を返すクロージャです。クロージャでtrue
は、フィルタリングされた配列で必要なオブジェクトを返すだけです。
NSPredicate predicateWithBlock:
APIで必要です。
bindings
辞書には、テンプレートの変数バインディングを含めることができます。
Clay Bridgesの回答に基づいて、ブロックを使用したフィルタリングの例を次に示します(yourArray
配列変数名とtestFunc
テスト関数の名前を)。
yourArray = [yourArray objectsAtIndexes:[yourArray indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return [self testFunc:obj];
}]];
filteredArrayUsingPredicate
あなたが不明瞭一種の目的を任意の述語を使用していないという事実は、スリムです。
Implicit conversion of 'NSUInteger' (aka 'unsigned long') to 'NSIndexSet * _Nonnull' is disallowed with ARC
... NSIndexSetsを期待しています
indexOfObjectPassingTest
代わりに誤って使用したことだと思いますindexesOfObjectsPassingTest
。見逃しやすいが、大きな違い:)
OS X 10.6 / iOS 4.0以降の場合は、NSPredicateよりもブロックの方が良いでしょう。参照してください-[NSArray indexesOfObjectsPassingTest:]
または便利な追加する独自のカテゴリを作成し-select:
たり-filter:
する方法(例)。
他の誰かにそのカテゴリの作成、テストなどをしてもらいたいですか?BlocksKit(配列ドキュメント)を確認してください。そして、そこにある多くによって発見されるより多くの例と言うには、例えばを探して、「選択はNSArrayのブロックカテゴリ」。
オブジェクトがすべて同様のタイプであると仮定すると、基準に使用している関数を呼び出すメソッドを、その基本クラスのカテゴリとして追加できます。次に、そのメソッドを参照するNSPredicateオブジェクトを作成します。
一部のカテゴリでは、関数を使用するメソッドを定義します
@implementation BaseClass (SomeCategory)
- (BOOL)myMethod {
return someComparisonFunction(self, whatever);
}
@end
次に、フィルタリングする場所はどこでも:
- (NSArray *)myFilteredObjects {
NSPredicate *pred = [NSPredicate predicateWithFormat:@"myMethod = TRUE"];
return [myArray filteredArrayUsingPredicate:pred];
}
もちろん、関数がクラス内から到達可能なプロパティとのみ比較する場合は、関数の条件を述語文字列に変換する方が簡単な場合があります。
NSPredicate
フィルターに収集した状態を構築するNEXTSTEPの方法があります(NSArray
、NSSet
、NSDictionary
)。
たとえば、2つの配列arr
とfilteredarr
:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",@"c"];
filteredarr = [NSMutableArray arrayWithArray:[arr filteredArrayUsingPredicate:predicate]];
Filteredarrには、文字cのみを含むアイテムが必ず含まれます。
SQLの背景が少しだけある人を覚えやすくするため
*--select * from tbl where column1 like '%a%'--*
1)select * from tbl- >コレクション
2)column1 like '%a%' ->NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",@"c"];
3)select * from tbl where column1 like '%a%' ->
[NSMutableArray arrayWithArray:[arr filteredArrayUsingPredicate:predicate]];
これが役に立てば幸い
NSArray + Xh
@interface NSArray (X)
/**
* @return new NSArray with objects, that passing test block
*/
- (NSArray *)filteredArrayPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate;
@end
NSArray + Xm
@implementation NSArray (X)
- (NSArray *)filteredArrayPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate
{
return [self objectsAtIndexes:[self indexesOfObjectsPassingTest:predicate]];
}
@end
このライブラリをチェックアウト
https://github.com/BadChoice/Collection
ループを二度と書くことのない、簡単な配列関数がたくさんあります
だからあなたはただ行うことができます:
NSArray* youngHeroes = [self.heroes filter:^BOOL(Hero *object) {
return object.age.intValue < 20;
}];
または
NSArray* oldHeroes = [self.heroes reject:^BOOL(Hero *object) {
return object.age.intValue < 20;
}];