があり、特定の基準を満たす元の配列からNSArray
新しいオブジェクトを作成したいと思います。NSArray
基準は、 を返す関数によって決定されますBOOL
。
を作成しNSMutableArray
、ソース配列を反復処理して、フィルター関数が受け入れるオブジェクトをコピーし、その不変バージョンを作成できます。
より良い方法はありますか?
があり、特定の基準を満たす元の配列からNSArray
新しいオブジェクトを作成したいと思います。NSArray
基準は、 を返す関数によって決定されますBOOL
。
を作成しNSMutableArray
、ソース配列を反復処理して、フィルター関数が受け入れるオブジェクトをコピーし、その不変バージョンを作成できます。
より良い方法はありますか?
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" }
Clay Bridges の回答に基づいて、ブロックを使用したフィルタリングの例を次に示します (yourArray
配列変数名とtestFunc
テスト関数の名前に変更します)。
yourArray = [yourArray objectsAtIndexes:[yourArray indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return [self testFunc:obj];
}]];
OS X 10.6/iOS 4.0 以降を使用している場合は、おそらく NSPredicate よりもブロックの方が適しています。独自のカテゴリ-[NSArray indexesOfObjectsPassingTest:]
を表示または作成して、便利な-select:
または-filter:
メソッドを追加します ( example )。
他の誰かにそのカテゴリを書いたり、テストしたりしてもらいたいですか? BlocksKit ( array docs )を確認してください。また、たとえば"nsarray block category select"を検索すると、さらに多くの例が見つかります。
オブジェクトがすべて同様のタイプであると仮定すると、条件に使用している関数を呼び出すメソッドを基本クラスのカテゴリとして追加できます。次に、そのメソッドを参照する NSPredicate オブジェクトを作成します。
いくつかのカテゴリで、関数を使用するメソッドを定義します
@implementation BaseClass (SomeCategory)
- (BOOL)myMethod {
return someComparisonFunction(self, whatever);
}
@end
次に、フィルタリングする場所は次のとおりです。
- (NSArray *)myFilteredObjects {
NSPredicate *pred = [NSPredicate predicateWithFormat:@"myMethod = TRUE"];
return [myArray filteredArrayUsingPredicate:pred];
}
もちろん、関数がクラス内から到達可能なプロパティに対してのみ比較する場合は、関数の条件を述語文字列に変換する方が簡単な場合があります。
NSPredicate
NSArray
コレクション ( 、NSSet
、 )をフィルタリングする条件を構築する nextstep の方法ですNSDictionary
。
たとえば、2 つの配列arr
と を考えfilteredarr
ます。
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",@"c"];
filteredarr = [NSMutableArray arrayWithArray:[arr filteredArrayUsingPredicate:predicate]];
フィルタリングされたarrには、文字cのみを含むアイテムが確実に含まれます。
SQLのバックグラウンドがほとんどない人を覚えやすくするために
*--select * from tbl where column1 like '%a%'--*
1) select * from tbl --> コレクション
2) '%a%' のような column1 -->NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",@"c"];
3) select * from tbl where column1 like '%a%' -->
[NSMutableArray arrayWithArray:[arr filteredArrayUsingPredicate:predicate]];
これが役立つことを願っています
このライブラリをチェックアウト
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;
}];
使用できる別のカテゴリ メソッド:
- (NSArray *) filteredArrayUsingBlock:(BOOL (^)(id obj))block {
NSIndexSet *const filteredIndexes = [self indexesOfObjectsPassingTest:^BOOL (id _Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
return block(obj);
}];
return [self objectsAtIndexes:filteredIndexes];
}