私は、特定のオブジェクトがいくつあるかを確認する方法を見つけようとしてきましたNSArray
。
私はドキュメントを調べましたが、これには事前に作成された方法がないと確信しています。また、私はここSOで何も見つけることができません。
誰かがこれを行うための良い方法を知っていますか?私は真剣に何も思い付くことができないので。
この特定のケースでは、文字列を含む配列(ほとんどの場合、それぞれがいくつか)があり、配列内で要求したものに一致する文字列の数を数えたいと思います。
私は、特定のオブジェクトがいくつあるかを確認する方法を見つけようとしてきましたNSArray
。
私はドキュメントを調べましたが、これには事前に作成された方法がないと確信しています。また、私はここSOで何も見つけることができません。
誰かがこれを行うための良い方法を知っていますか?私は真剣に何も思い付くことができないので。
この特定のケースでは、文字列を含む配列(ほとんどの場合、それぞれがいくつか)があり、配列内で要求したものに一致する文字列の数を数えたいと思います。
これがデータ構造の主な用途であり、順序が重要でない場合は、NSCountedSet
この問題を効率的に解決するために特別に使用するものに切り替えることを検討してください。
順序付けられたコレクションが必要で、オブジェクトの膨大なセットがない場合は、高速列挙の回答が最善のアプローチです。
オブジェクトがどこにあるかを知りたい場合は、を使用してindexesOfObjectsPassingTest:
ください。
indexesOfObjectsWithOptions:passingTest:
膨大な数のオブジェクトがある場合は、オプションを使用して検討しNSEnumerationConcurrent
ます。これにより、複数のコアでアレイを検索できるようになります。(これはマルチコアデバイスでのみ高速になる可能性があり、コレクションが非常に大きい場合にのみ高速になる可能性があります。同時実行が高速になると想定する前に、絶対にテストする必要があります。)最終的なカウントが必要な場合でも、特定のデータセットがこのメソッドを使用してから、最終的なインデックスセットで使用する方が速い場合があります。count
これには実際に方法があります。- (NSIndexSet *)indexesOfObjectsPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate
NSIndexSet *indexes = [array indexesOfObjectsPassingTest:^(id obj, NSUInteger index, BOOL *stop) {
return [obj isEqualTo:myOtherObject];
}];
の場合のように聞こえNSCountedSet
ます。これは、initWithArray:
初期化子を使用して目的の処理を実行します。
// Example array of strings
NSArray *array = [NSArray arrayWithObjects:
@"Joe", @"Jane", @"Peter", @"Paul",
@"Joe", @"Peter", @"Paul",
@"Joe",
@"Jane", @"Peter",
nil];
NSCountedSet *countedSet = [[NSCountedSet alloc] initWithArray: array];
// for-in will let you loop over the counted set
for (NSString *str in countedSet) {
NSLog(@"Count of %@: %ld", str, (long)[countedSet countForObject:str]);
}
- (NSUInteger) objectCountInArray:(NSArray *)array
matchingString:(NSString *)stringToMatch {
NSUInteger count = 0;
for (NSString *string in array) {
count += [string isEqualToString:stringToMatch] ? 1 : 0;
}
return count;
}
これを拡張して、オブジェクトを取得して BOOL を返すブロックを使用することができます。次に、それを使用して、必要な配列を比較できます。
1 つのアプローチは、反復してチェックすることです。
- (int)repeatsOf:(NSString *)repeater inArray:(NSArray *)array {
int count = 0;
for (NSString *item in array) {
if ([item isEqualToString:repeater]) {
count++;
}
}
return count;
}
単純なループを試すことができます。needle
が参照文字列であり、文字列のNSArrayarray
であるとします。
unsigned int n = 0;
for (NSString * str in array)
{
if ([needle isEqualToString:str])
{
++n;
}
}
n
に等しい文字列の数を保持するようになりましたneedle
。
次のような関数を定義できます。
- (int)countStringsThatMatch:(NSString*)match inArray:(NSArray*)array
{
int matches = 0;
for (id string in array) {
if ([string isEqualToString:match]) {
matches++;
}
}
return matches;
}
そして、次のように使用します。
int count = [self countStringsThatMatch:@"someString" inArray:someArray];