Binary Search NSArray

Though CFArray comes with binary search capability, NSArray does not – at least not within the iPhone SDK. The indexOfObject:inSortedRange:options:usingComparator: can’t be found.

Plus the CFArrayBSearchValues doesn’t tell you whether the key actually is part of the list or not. That’s what the Java JDK does, so let’s implement some category methods

-(NSInteger)binarySearch:(id)key usingSelector:(SEL)comparator;
-(NSInteger)binarySearch:(id)key usingSelector:(SEL)comparator inRange:(NSRange)range;
-(NSInteger)binarySearch:(id)key usingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context;
-(NSInteger)binarySearch:(id)key usingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context inRange:(NSRange)range;
-(NSInteger)binarySearch:(id)key usingDescriptors:(NSArray *)sortDescriptors;
-(NSInteger)binarySearch:(id)key usingDescriptors:(NSArray *)sortDescriptors inRange:(NSRange)range;

ourselves, like

-(NSInteger)binarySearch:(id)key usingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context inRange:(NSRange)range
    NSLogD(@"[NSArray(MroBinarySearch) binarySearch:%@ usingFunction:]", key);
    if(self.count == 0 || key == nil || comparator == NULL)
        return [self binarySearch:key usingSelector:nil inRange:range];
//	check overflow?
    NSInteger min = range.location;
    NSInteger max = range.location + range.length - 1;
    while (min < = max)
        const NSInteger mid = min + (max - min) / 2;
        switch (comparator(key, [self objectAtIndex:mid], context))
            case NSOrderedSame:
                return mid;
            case NSOrderedDescending:
                min = mid + 1;
            case NSOrderedAscending:
                max = mid - 1;
    return -(min + 1);

See the full interface + implementation + testcase without html encoding dirt at github.

Comments 1

  1. bob wrote:

    „return -(min + 1);“ can also be written as „return ~min;“

    Posted 21 Apr 2011 at 8:05 am

Post a Comment

Your email is never published nor shared. Required fields are marked *