web-dev-qa-db-ja.com

配列内のオブジェクトのインデックスを取得して、他の配列内の対応するオブジェクトを検索します

2つのアレイがあります。 1つは名前の配列で、もう1つは「はい」または「いいえ」というタイトルの文字列で構成される配列です。 「name」配列の各名前のインデックスパスは、「Yes/No」配列の同じインデックスパスに対応しています。例えば:

Names Array | Yes/No Array
Person 1    | Yes
Person 2    | No
Person 3    | Yes

人の名前を検索し(おそらくそのインデックスパスを取得する)、「はい」または「いいえ」の配列で「はい」または「いいえ」のどちらであるかを確認する最も簡単な方法は何ですか?

また、「インデックスパス」が適切な用語かどうかはわかりません。そうでない場合は、オブジェクトが配列内にある数を意味します。

19
Preston

NSArrayにはindexOfObjectというメソッドがあり、対応する配列値がanObjectに等しい最小のインデックスを返すか、そのようなオブジェクトが見つからない場合はNSNotFoundを返します。名前の配列がソートされていない場合は、これを使用してインデックスを取得し、Yes/No配列にプラグインできます。つまり、これらの線に沿った何か:

NSString *answer = nil;
NSUInteger index = [namesArray indexOfObject:@"John Smith"];
if (index != NSNotFound) {
    answer = [yesNoArray objectAtIndex:index];
}
return answer;

Bavariousは私が想定している場所で質問をするので、名前の配列をアルファベット順に並べ替える場合は、これがより良い方法です。

int index = [self findName:@"John Smith"];
NSString *answer = nil;
if (index >= 0) {
    answer = [yesNoArray objectAtIndex:index];
}
return answer;

ここで、関数findNameは単純なバイナリ検索です。

-(int)findName:(NSString *)name {
    int min, mid, max;
    NSComparisonResult comparisonResult;
    min = 0;
    max = [namesArray count]-1;
    while (min <= max) {
        mid = min + (max-min)/2;
        comparisonResult = [name compare:[namesArray objectAtIndex:mid]];
        if (comparisonResult == NSOrderedSame) {
            return mid;
        } else if (comparisonResult == NSOrderedDescending) {
            min = mid+1;
        } else {
            max = mid-1;
        }
    }   
    return -1;  
}
31
PengOne

2つのアレイの同期を維持しようとすると、問題が発生します。もちろんできますが、1つの配列を変更するときはいつでも、もう1つの配列に対応する変更を加えることを忘れないでください。データを保存する方法を再考することにより、自分自身に好意を示し、そのクラスのバグ全体を回避します。

この場合、{person、boolean}ペアを持っています。 1つのオプションは、各ペアを辞書として格納し、それらの辞書の配列を保持することです。データの数を2つ以上に増やす可能性がある場合、これは特に良い計画です。別のオプションは、キーが人名で値がイエス/ノーの値である辞書を使用することです。これにより、質問に対する答えが非常に簡単になります。

NSString *yesOrNo = [personDictionary objectForKey:personName];

元の質問に戻って、まだ2つの配列がある場合、easiestすべきことは、探している人が見つかるまでperson配列を反復処理し、そのインデックスを取得することです名前、次にyes/no配列で対応する値を検索します。

for (person in peopleArray) {
    if ([person isEqualToString:thePersonYoureLookingFor]) {
        yesNoValue = [yesNoArray objectAtIndex:[peopleArray indexOfObject:person];
        break;
    }
}

リストの人数が多すぎなければ問題ありません。リストが大きくなる可能性がある場合は、バイナリ検索を実行できるように、person配列をソートしたままにしておくことをお勧めします。ただし、ここでの問題は、yes/no配列が別個であるため、yes/no配列を正しい順序で維持しながらpersonArrayをソートすることが複雑になることです。

9
Caleb

以下のコードを使用することもできます。

NSSortDescriptor *_lastDescriptor = [[NSSortDescriptor alloc] initWithKey:@"" ascending:YES];
NSArray *_lastArray = [NSArray arrayWithObject:_lastDescriptor];


firstCharacterArray = (NSMutableArray *)[[nameIndexesDictionary allKeys]      
sortedArrayUsingDescriptors:_lastArray];
//firstCharacterArray = (NSMutableArray *)[[nameIndexesDictionary allKeys]                    
sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

for (NSString *eachlastIndex in firstCharacterArray)
{
NSSortDescriptor *lastDescriptor = [[NSSortDescriptor alloc] initWithKey:@""
                                                               ascending:YES];
//selector:@selector(localizedCaseInsensitiveCompare:)] ;
NSArray *descriptorslast = [NSArray arrayWithObject:lastDescriptor];
[[nameIndexesDictionary objectForKey:eachlastIndex]     
sortUsingDescriptors:descriptorslast];
[lastDescriptor release];
}
2
Dinesh_

indexOfObjectメソッドを使用して、要素のインデックスを取得できます。

例えば

これはあなたのオブジェクトのインデックスを与えます

  NSInteger index = [yourArray indexOfObject:objectName];

別の配列から対応する要素を表示するには

[anotherArray objectAtIndex:index];

これでうまくいきました。お役に立てれば。

0
Pradumna Patil