Sorting an NSArray of NSDictionary objects, based on values in NSDictionary


How to use sortedArrayUsingFunction

Today I came across a requirement where I had to Sort an NSArray. Each element of the array had a NSDictionary which had only one element, which was a NSArray. Structure was like:

NSArray

—->NSDictionary

—->—->”somekey1″ – NSArray [val1, val2, val3… val-n]

—->NSDictionary

—->—->”somekey2″ – NSArray [val1, val2, val3… val-m]

—->NSDictionary

—->—->”somekey3″ – NSArray [val1, val2, val3… val-o]

:

:

—->NSDictionary

—->—->”somekey-x” – NSArray [val1, val2, val3… val-w]

(where n!=m!=o!=w)

I wanted this NSArray to be sorted so that the NSDictionary with the largest number of NSArray values in it should come on sorted.

After looking at the available options in Apple’s Documentation here I decided to define a selector (‘delegate’ for other .NET folks like me) and provide the selector to the sortedArrayUsingFunction method available for an NSArray.

The sorting function looks like this

NSInteger sortByArrayCount(id dictionary1, id dictionary2, void *reverse)
{

    NSMutableDictionary *dict1 = (NSMutableDictionary *)dictionary1;
    NSMutableDictionary *dict2 = (NSMutableDictionary *)dictionary2;

    NSArray *arr1 = (NSArray *)[[dict1 objectEnumerator] nextObject];
    NSArray *arr2 = (NSArray *)[[dict2 objectEnumerator] nextObject];

    NSLog(@"Count of Array 1: %d, Array 2: %d", [arr1 count], [arr2 count]);
    if(*(BOOL *)reverse == YES)
    {
        return ([arr2 count] > [arr1 count]);
    }
    else
    {
        return ([arr1 count] > [arr2 count]);
    }
}

I think the code is quite self explanatory, we convert the values passed into the method. Then extract the first element in the dictionary as NSArray, finally I check if reverse==YES is passed or not this flag indicates whether you want a Descending sort or not. Finally do the comparison.

To sort an array you call it as follows:


NSArray *sortedArray;
BOOL reverseSort = NO;
sortedArray = [catList sortedArrayUsingFunction:sortByArrayCount context:&reverseSort];

Point to note here is once you have got the NSDictionary you could make the sorting condition on any of the values in the dictionary. For example string compare the Key of the two inputs.

The sortArrayByFunction method offers a lot of flexibility in terms of deciding how you want to sort. My case was a unique one.

Other options to explore are ofcourse using sortDescriptors if you wanted to sort based on string values in NSArray of NSDictionaries.

That’s about it for now. Have fun.

(Yay! to my first iOS article)

Advertisements
Tagged , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: