现在的位置: 首页 > 综合 > 正文

NSArray排序问题

2012年04月10日 ⁄ 综合 ⁄ 共 1602字 ⁄ 字号 评论关闭

问:

I have some data like this :

1, 111, 2, 333, 45, 67, 322, 4445

NSArray *array = [[myData allKeys]sortedArrayUsingSelector: @selector(compare:)];

If I run this code, it sorted like this:

1, 111, 2,322, 333, 4445, 45, 67,

but I actually want this:

1, 2, 45, 67, 111, 322, 333, 4445

How can I implement it? thz u.

答:

Expanding on Paul Lynch's answer, here's an example I have doing exactly this using a comparison method as a category on NSString. This code handles only the case of numbers followed by optional non-numeric qualifiers, but you could extend it to handle cases like "1a10" etc. if desired.

Once you create the category method, you just need to do

[[myData allKeys]sortedArrayUsingSelector:@selector(psuedoNumericCompare:)]

@interface NSString (Support) 
- (NSComparisonResult) psuedoNumericCompare:(NSString *)otherString;
@end

@implementation NSString (Support)

// "psuedo-numeric" comparison
// -- if both strings begin with digits, numeric comparison on the digits
// -- if numbers equal (or non-numeric), caseInsensitiveCompare on the remainder

- (NSComparisonResult) psuedoNumericCompare:(NSString *)otherString {

NSString *left = self;
NSString *right = otherString;
NSInteger leftNumber, rightNumber;


NSScanner *leftScanner = [NSScanner scannerWithString:left];
NSScanner *rightScanner = [NSScanner scannerWithString:right];

// if both begin with numbers, numeric comparison takes precedence
if ([leftScanner scanInteger:&leftNumber] && [rightScanner scanInteger:&rightNumber]) {
if (leftNumber < rightNumber)
return NSOrderedAscending;
if (leftNumber > rightNumber)
return NSOrderedDescending;

// if numeric values tied, compare the rest
left = [left substringFromIndex:[leftScanner scanLocation]];
right = [right substringFromIndex:[rightScanner scanLocation]];
}

return [left caseInsensitiveCompare:right];
}
@end

抱歉!评论已关闭.