2012-09-15 15 views
9

並べて並べ替える必要がある配列がいくつかあります。2つのNSArrayを並べて並べる

たとえば、最初の配列は@[@"Joe", @"Anna", @"Michael", @"Kim"]と の名前を持ち、もう一方の配列はアドレスが@[@"Hollywood bld", @"Some street 3", @"That other street", @"country road"]であり、配列のインデックスが一緒になっています。 「ジョー」は「ハリウッドのビル」などに住んでいます。

名前配列をアルファベット順にソートし、アドレス配列を並べて並べて、 "Joe"と同じインデックスを持つ "Hollywood bld"を作成します。私は

NSSortDescriptor *sort=[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:NO]; 
[myArray sortUsingDescriptors:[NSArray arrayWithObject:sort]]; 

で1つの配列のアルファベットを並べ替える方法を知っているが、二番目の配列が適切な順序を使用してソート得るための簡単な方法はありますか?

おそらく、ソート前と後のオブジェクトのインデックスを追跡することによってこれを行うことができますが、多分それは次にあなたにこれらのオブジェクトを格納ハスこれらのプロパティのすべて

Person : NSObject 

@property (nonatomic, copy) NSString *name; 
@property (nonatomic, copy) NSString *addresss; 

単一のオブジェクトを持つ容易になるだろう

答えて

11
  1. 第アレイ
  2. が両方の配列

例再順序順列を使用nameキーに従って最初p[i]=i

  • ソート順列に設定順列アレイを作成します。最初の配列が{"quick", "brown", "fox"}であるとします。置換は{0, 1, 2}で始まり、ソート後に{1, 2, 0}になります。ここで順列配列を調べ、必要に応じて元の配列と2番目の配列を並べ替えることができます。

    NSArray *first = [NSArray arrayWithObjects: @"quick", @"brown", @"fox", @"jumps", nil]; 
    NSArray *second = [NSArray arrayWithObjects: @"jack", @"loves", @"my", @"sphinx", nil]; 
    NSMutableArray *p = [NSMutableArray arrayWithCapacity:first.count]; 
    for (NSUInteger i = 0 ; i != first.count ; i++) { 
        [p addObject:[NSNumber numberWithInteger:i]]; 
    } 
    [p sortWithOptions:0 usingComparator:^NSComparisonResult(id obj1, id obj2) { 
        // Modify this to use [first objectAtIndex:[obj1 intValue]].name property 
        NSString *lhs = [first objectAtIndex:[obj1 intValue]]; 
        // Same goes for the next line: use the name 
        NSString *rhs = [first objectAtIndex:[obj2 intValue]]; 
        return [lhs compare:rhs]; 
    }]; 
    NSMutableArray *sortedFirst = [NSMutableArray arrayWithCapacity:first.count]; 
    NSMutableArray *sortedSecond = [NSMutableArray arrayWithCapacity:first.count]; 
    [p enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
        NSUInteger pos = [obj intValue]; 
        [sortedFirst addObject:[first objectAtIndex:pos]]; 
        [sortedSecond addObject:[second objectAtIndex:pos]]; 
    }]; 
    NSLog(@"%@", sortedFirst); 
    NSLog(@"%@", sortedSecond); 
    
  • +1

    偉大なスクリプト。それがもっと簡単だったら欲しいですが、それはちょうどプログラミングの仕方だと思います。 –

    3

    name、またはaddressキーパスで並べ替えることができる1つの配列

    4

    最も良い方法は、データを再構成して1つの配列しか持たないようにすることです。あなたの例では、名前と住所の両方を持つ新しいクラスを作成し、配列に入れて名前でソートするのが最も理にかなっています。

    +0

    辞書の配列を作成してください。各辞書には、名前と対応するアドレスが含まれています。 – Caleb

    +2

    本当に、辞書は常に、誰かがそれをうまく分類するためにデータの目的について十分気にしていないという気持ちを私に残す。 :-) –

    10

    まず、2つのアレイをこのような並列方法で並べ替える必要があるアーキテクチャを再検討したいことがあります。しかし、それを言っておけば、2つの配列の要素をペアにしておく一時的な辞書の配列を作成することでそれを行うことができます。

    は、その後、組み合わせ配列をソートし、要求されたとして再度、ソートされた二つの配列を抽出します。

    オリジナルデータ:

    NSArray *names  = @[@"Joe", @"Anna", @"Michael"]; 
    NSArray *addresses = @[@"Hollywood bld", @"Some street 3", @"That other street"]; 
    

    実際のソートコード:

    NSMutableArray *combined = [NSMutableArray array]; 
    
    for (NSUInteger i = 0; i < names.count; i++) { 
        [combined addObject: @{@"name" : names[i], @"address": addresses[i]}]; 
    } 
    
    [combined sortUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]]; 
    
    names  = [combined valueForKey:@"name"]; 
    addresses = [combined valueForKey:@"address"]; 
    

    ていることに注意してくださいアレイ上で使用されるvalueForKey:は、同じサイズの新しい配列を抽出し、元の配列内のオブジェクトのプロパティで生成されます。この場合、元の配列から新しい配列を作成し、必要に応じてソートします。

    このアプローチは、ほんの数行のコードしか必要とせず、必要に応じて追跡してデバッグするのが簡単です。

    +0

    '-valueForKey:'をうまく使います。 – jrc

    関連する問題