Andy Jacobs
Andy Jacobs

Reputation: 15245

Sort an NSArray by another nsarray with ids

i have 2 nsarrays 1 with nsdictionary's another with nsnumbers

NSArray *arr1 = @[@{@"id":@1},@{@"id":@2},@{@"id":@3},@{@"id":@4}];
NSArray *arr2 = @[@3,@1,@4,@2];

and i want to sort my arr1 through their id following the order of arr2 is this possible?

Upvotes: 2

Views: 235

Answers (3)

Ramy Al Zuhouri
Ramy Al Zuhouri

Reputation: 21996

Here is how you can do it by using a custom comparator:

NSArray* sorted= [arr1 sortedArrayUsingComparator: ^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) {
    return [arr2 indexOfObject:obj1[@"id"]] - [arr2 indexOfObject:[obj2[@"id"]];
}];

I exploited the fact that NSComparisonResult has +1 to represent an ascending order, -1 for descending and 0 to represent the same order.

Upvotes: 3

Brian Nickel
Brian Nickel

Reputation: 27560

The problem with using sortedArrayUsingComparator: is you start dealing with O(n^2) lookup times. For each sort comparison in the first array, you have to do a lookup in the second array.

Your best bet is to take advantage of a hash table to reduce that to O(n) average complexity.

Your first step is to create a dictionary using id as a key. The result would look something like @{@1: @{@"id":@"1"}, ...}. Then you just have to construct an array by looping through arr3 and grabbing the values.

NSArray *arr1 = @[@{@"id":@1},@{@"id":@2},@{@"id":@3},@{@"id":@4}];
NSArray *arr2 = @[@3,@1,@4,@2];

NSMutableDictionary *map = [NSMutableDictionary dictionary];
for (NSDictionary *item in arr1) {
    map[item[@"id"]] = item;
}

NSMutableArray *arr3 = [NSMutableArray array];
for (id key in arr2) {
    [arr3 addObject:map[key]];
}

This solution of course assumes parity between the two arrays. If arr2 has an element not in arr1 it will crash when trying to add nil to arr3. If arr1 has a value not in arr2 it will be excluded from arr3. These are risks you will have to address based on your requirements.

Upvotes: 5

Slashik
Slashik

Reputation: 325

- (NSArray*) sortedArray
{
    NSArray *arr1 = @[@{@"id":@1},@{@"id":@2},@{@"id":@3},@{@"id":@4}];
    NSArray *arr2 = @[@3,@1,@4,@2];

    NSMutableArray *mutableArray = [NSMutableArray new];
    for (NSNumber *number in arr2)
    {
        for (NSDictionary* dictionary in arr1)
        {
            NSNumber *number2 = dictionary[@"id"];
            if ([number isEqual:number2])
            {
                [mutableArray addObject:dictionary];
                break;
            }
        }
    }
    return mutableArray;
}

Upvotes: 1

Related Questions