2

I´m searching for a sorted Array or Map (Dict...whatever) in Objective-C on iOS.

Is there something comparable (sorting when inserting) or do I have to override the getter/setter and sort the data structures 'on my own'? I know, there´s the possiblity to sort arrays, but I´m wondering if there´s the 'automatic' way like a TreeMap in Java, where you can put an Entry in and it is directly inserted at the right place.

Cheers,

Marc

stk
  • 6,311
  • 11
  • 42
  • 58
  • Not a dupe, but the accepted answer is useful: http://stackoverflow.com/questions/1648059/is-the-objective-c-dictionary-an-ordered-container – Matt K Apr 03 '12 at 13:35
  • thanks, that helped...but I hoped to avoid using yet another library in my project. – stk Apr 03 '12 at 13:38
  • You could implement your own container, or keep an array of the hash keys in whatever order you want them sorted. – Matt K Apr 03 '12 at 14:01
  • 1
    @mkb: That question asks about *ordered* container (i.e. by insertion order), which is completely different than a *sorted* container – user102008 May 04 '12 at 21:35

1 Answers1

0

Probably the easiest thing to do, if you want an array is to create a category on NSMutableArray with a method that inserts an object in the right place. This is a bit unsatisfactory, however (there's nothing to stop you from inserting objects using the normal method and breaking the ordering), so you probably want your own collection class. You can create this easily by wrapping an NSMutableArray and a comparator in a new class. e.g.

@interface MyOrderedArray : NSObject <NSFastEnumeration>

-(id) initWithComparator: (NSComparator) anOrdering;

-(void) insertObject: (id) aNewObject;

// methods to access objects from the array

@end

@implementation MyOrderedArray
{
   NSComaparator theOrdering;
   NSMutableArray* backingArray;
}

-(id) initWithComparator: (NSComparator) anOrdering
{
    self = [super init];
    if (self != nil)
    {
        theOrdering = [anOrdering copy];
        backingArray = [[NSMUtableArray alloc] init];
}

-(id) insertObject: (id) newObject
{
    // use a binary search to find the index and insert the object there
}

Other methods can be passed to the backing array to implement e.g.

-(NSUInteger) count
{
    return [backingArray count];
}

and this one will be useful:

- (NSUInteger)countByEnumeratingWithState: (NSFastEnumerationState*) state 
                                  objects: (id*) stackbuf 
                                    count: (NSUInteger) len
{
    return [backingArray countByEnumeratingWithState: state 
                                             objects: stackbuf 
                                               count: len];
}
JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • this method is inefficient: inserting an element would take O(n); while in a self-balancing binary search tree implementation insertion would take O(log n) – user102008 May 04 '12 at 21:39
  • @user102008: Did you notice that I did not provide an implementation for `-insertObject:` and that the placeholder comment says "use a binary search"? Binary search is O(log n) and you don't have to write a whole new container class – JeremyP May 09 '12 at 09:12
  • but then to insert it requires O(n) – user102008 May 09 '12 at 19:18
  • @user102008: Are you making an unwarranted assumption about the implementation of NSMutableArray? – JeremyP May 10 '12 at 08:09
  • 1
    And can you think of any implementation where that wouldn't be true? – user102008 May 10 '12 at 23:27
  • @user102008: are you saying you can't think of an implementation for an ordered indexed collection (which is what an NSArray is) where insertion can be implemented in less than O(n) time. – JeremyP May 11 '12 at 08:25
  • A list which has O(1) random access must have O(n) insertion. A list which has O(1) insertion (given an iterator) must have O(n) random access. Or you can have O(log n) random access and O(log n) insertion which is something like a self-balancing binary search tree like i mentioned earlier. – user102008 May 12 '12 at 01:41
  • @ user102008: You should know that a Cocoa NSArray can have different implementations depending partly on how many elements there are in it. http://ridiculousfish.com/blog/posts/array.html – JeremyP May 14 '12 at 09:25
  • I know that. I did not assume any specific implementation. – user102008 May 14 '12 at 18:40