Re: kCFCompareNumerically
Re: kCFCompareNumerically
- Subject: Re: kCFCompareNumerically
- From: Norbert Heger <email@hidden>
- Date: Tue, 15 Jan 2002 02:06:19 +0100
I wrote:
>
I've attached a tested solution that seems to work properly.
It seems the mailing list server didn't like my attachments.
Let's try plain ASCII instead...
Best Regards, Norbert
_____________________________________________
Norbert Heger, Objective Development
http://www.obdev.at/
---- NSString_ODCompareNumerically.h ---------------------------------------
#import <Foundation/Foundation.h>
@interface NSString (ODCompareNumerically)
- (NSComparisonResult)compareNumerically:(NSString *)otherString;
@end
---- NSString_ODCompareNumerically.m ---------------------------------------
#import "NSString_ODCompareNumerically.h"
typedef unichar(* unichar_IMP)(id,SEL,...);
static inline BOOL isDecimalDigit(unichar c) { return c>='0' && c<='9'; }
@implementation NSString (ODCompareNumerically)
- (unsigned int)lengthOfNonnumericCommonPrefixWithString:(NSString *)aString
{
unsigned int i, count = MIN([self length], [aString length]);
unichar_IMP imp1 = (unichar_IMP)
[self methodForSelector:@selector(characterAtIndex:)];
unichar_IMP imp2 = (unichar_IMP)
[aString methodForSelector:@selector(characterAtIndex:)];
for (i = 0; i < count; i++) {
unichar c1 = imp1(self, @selector(characterAtIndex:), i);
unichar c2 = imp2(aString, @selector(characterAtIndex:), i);
if (c1 != c2 || isDecimalDigit(c1) || isDecimalDigit(c2)) { break; }
}
return i;
}
- (NSComparisonResult)compareNumerically:(NSString *)otherString
{
unsigned int prefixLength =
[self lengthOfNonnumericCommonPrefixWithString:otherString];
NSString *suffix = [self substringFromIndex:prefixLength];
NSString *otherSuffix = [otherString substringFromIndex:prefixLength];
unsigned int suffixLength = [suffix length];
unsigned int otherSuffixLength = [otherSuffix length];
if (suffixLength == 0 || otherSuffixLength == 0) {
return (suffixLength == otherSuffixLength)
? NSOrderedSame
: (suffixLength == 0
? NSOrderedAscending
: NSOrderedDescending);
} else {
BOOL suffixHasNumericPrefix =
isDecimalDigit([suffix characterAtIndex:0]);
BOOL otherSuffixHasNumericPrefix =
isDecimalDigit([otherSuffix characterAtIndex:0]);
if (suffixHasNumericPrefix && otherSuffixHasNumericPrefix) {
int value = [suffix intValue];
int otherValue = [otherSuffix intValue];
return (value == otherValue)
? NSOrderedSame
: (value < otherValue
? NSOrderedAscending
: NSOrderedDescending);
} else {
if (suffixHasNumericPrefix) {
return NSOrderedAscending;
} else if (otherSuffixHasNumericPrefix) {
return NSOrderedDescending;
} else {
return [suffix compare:otherSuffix];
}
}
}
}
@end