如何让sortedArrayUsingSelector使用整数来排序而不是String?

Tat*_*tat 6 sorting iphone nsarray

我有一些这样的数据:

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

NSArray *array = [[myData allKeys]sortedArrayUsingSelector: @selector(compare:)];
Run Code Online (Sandbox Code Playgroud)

如果我运行此代码,它的排序如下:

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

但我其实想要这个:

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

我该如何实现它?你.

Dav*_*har 21

扩展Paul Lynch的答案,这是一个例子,我使用比较方法作为一个类别NSString.此代码仅处理数字后跟可选的非数字限定符的情况,但如果需要,您可以扩展它以处理"1a10"等情况.

创建类别方法后,您只需要这样做

[[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];
}
Run Code Online (Sandbox Code Playgroud)


lic*_*lac 15

您可以使用NSString的-[compare:options:]函数和NSNumericSearch选项以数字方式比较NSStrings,而不必先将它们转换为NSIntegers(这可能非常昂贵,尤其是在较长的循环中).

由于您要使用NSArray,您可以使用NSSortDescriptor +[sortDescriptorWithKey:ascending:comparator:](或者-initWithKey:ascending:comparator:如果您想要一个预先保留的对象)相同的功能来执行基于块的比较,如下所示:

[NSSortDescritor sortDescriptorWithKey:@"myKey"
                             ascending:NO
                            comparator:^(id obj1, id obj2)
    {
        return [obj1 compare:obj2 options:NSNumericSearch];
    }
];
Run Code Online (Sandbox Code Playgroud)

使用此方法排序将得到与David的答案相同的结果,但无需自己处理NSScanner.