125

があり、特定の基準を満たす元の配列からNSArray新しいオブジェクトを作成したいと思います。NSArray基準は、 を返す関数によって決定されますBOOL

を作成しNSMutableArray、ソース配列を反復処理して、フィルター関数が受け入れるオブジェクトをコピーし、その不変バージョンを作成できます。

より良い方法はありますか?

4

9 に答える 9

144

NSArrayNSMutableArray配列の内容をフィルタリングするメソッドを提供します。指定された述語に一致するレシーバー内のオブジェクトを含む新しい配列を返す、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" }
于 2008-09-21T05:43:47.087 に答える
50

Clay Bridges の回答に基づいて、ブロックを使用したフィルタリングの例を次に示します (yourArray配列変数名とtestFuncテスト関数の名前に変更します)。

yourArray = [yourArray objectsAtIndexes:[yourArray indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return [self testFunc:obj];
}]];
于 2012-11-08T12:14:23.347 に答える
46

OS X 10.6/iOS 4.0 以降を使用している場合は、おそらく NSPredicate よりもブロックの方が適しています。独自のカテゴリ-[NSArray indexesOfObjectsPassingTest:]を表示または作成して、便利な-select:または-filter:メソッドを追加します ( example )。

他の誰かにそのカテゴリを書いたり、テストしたりしてもらいたいですか? BlocksKit ( array docs )を確認してください。また、たとえば"nsarray block category select"を検索すると、さらに多くの例が見つかります。

于 2010-10-04T16:22:44.910 に答える
17

オブジェクトがすべて同様のタイプであると仮定すると、条件に使用している関数を呼び出すメソッドを基本クラスのカテゴリとして追加できます。次に、そのメソッドを参照する NSPredicate オブジェクトを作成します。

いくつかのカテゴリで、関数を使用するメソッドを定義します

@implementation BaseClass (SomeCategory)
- (BOOL)myMethod {
    return someComparisonFunction(self, whatever);
}
@end

次に、フィルタリングする場所は次のとおりです。

- (NSArray *)myFilteredObjects {
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"myMethod = TRUE"];
    return [myArray filteredArrayUsingPredicate:pred];
}

もちろん、関数がクラス内から到達可能なプロパティに対してのみ比較する場合は、関数の条件を述語文字列に変換する方が簡単な場合があります。

于 2008-11-21T07:17:39.610 に答える
3

NSPredicateNSArrayコレクション ( 、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]];

これが役立つことを願っています

于 2013-04-04T10:51:50.977 に答える
0

このライブラリをチェックアウト

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;
}];
于 2016-08-29T17:56:03.703 に答える
0

使用できる別のカテゴリ メソッド:

- (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];
}
于 2021-01-18T02:07:49.097 に答える