I use this technique a lot with SQLitePersistentObjects on the iPhone to avoid loading objects into memory just to display one or two values from an object, for example, to put in a table view. When you have objects that contain UIImages or NSDatas, doing this can really keep your memory footprint way down, which is a very good thing on a resource-constrained device. On the iPhone, I'm a big fan of paired arrays. I don't use them so much on the Mac, but they certainly have their uses.
But, there is one really annoying thing about paired arrays: Sorting them. It's just not fun. NSMutableArray is set up to sort based on the values in its own array, not on the values in another array. So, if you want to sort both the key and value arrays based on the values in the array of keys, how do you do it? There's no easy, built-in way.
Well, if you've followed this blog for any length of time, you know that I really, really like Objective-C categories. Here's a new one - it lets you sort multiple arrays based on the values in one array. It uses exactly the same sorting algorithm as NSMutableArray I believe - a shell sort. I don't work for Apple and don't have access to their code, so I don't know for sure that they still do it this way, but the old NeXTSTEP/OPENSTEP sort was done this way, and the GNUStep sort is still done this way, so I'm guessing that Apple's Foundation Kit version of NSMutableArray still works this way, though I'm certainly open to more optimized sorting algorithms if you want to tweak it.
Here is an example of using this category, using three paired arrays, one with numbers, and two others with those numbers spelled out in different languages, and sorting all three values based on the numbers.
NSMutableArray *array1 = ;
NSMutableArray *array2 = ;
NSMutableArray *array3 = ;
;
After the call to sortArrayUsingSelector:withPairedArrays:, the three arrays will all be in numeric order, so array2 will look like this:
One, Two, Three, Four, Five, Sixand array3 will look like this:
Un, Deux, Trois, Quatre, Cinq, SixPretty cool, huh? Here's the code:
NSMutableArray-MultipleSort.h
//
// NSMutableArray-MultipleSort.h
// iContractor
//
// Created by Jeff LaMarche on 1/16/09.
// Copyright 2009 Jeff LaMarche. All rights reserved.
//
// This category on NSMutableArray implements a shell sort based on the old NeXT example
// SortingInAction. It is functionally identical to sortArrayUsingSelector: except that
// it will sort other paired arrays based on the comparison values of the original array
// this is for use in paired array situations, such as when you use one array to store
// keys and another array to store values. This is a variadic method, so you can sort
// as many paired arrays as you have.
// This source may be used, free of charge, for any purposes. commercial or non-
// commercial. There is no attribution requirement, nor any need to distribute
// your source code. If you do redistribute the source code, you must
// leave the original header comments, but you may add additional ones.
// Stride factor defines the size of the shell sort loop's stride. It can be tweaked
// for performance, though 3 seems to be a good general purpose value
// This compare method was taken from the GNUStep project. GNUStep is
// licensed under the LGPL, which allows such use.
static inline NSComparisonResult
{
NSComparisonResult (*imp)(id, SEL, id);
if
{
;
}
imp = (NSComparisonResult (*)(id, SEL, id))
;
if
{
;
}
return (*imp)(elem1, context, elem2);
}
NSMutableArray-MultipleSort.m
//
// NSMutableArray-MultipleSort.m
// iContractor
//
// Created by Jeff LaMarche on 1/16/09.
// Copyright 2009 Jeff LaMarche Consulting. All rights reserved.
//
// This source may be used, free of charge, for any purposes. commercial or non-
// commercial. There is no attribution requirement, nor any need to distribute
// your source code. If you do redistribute the source code, you must
// leave the original header comments, but you may add additional ones.
No comments:
Post a Comment