像 iPhone 上的地址簿排序一样对 NSString 的 NSArray 进行排序

发布于 2024-11-26 17:41:02 字数 173 浏览 2 评论 0原文

我有一个字符串(名称)数组

,我想像 iphone 上的地址簿对它们进行排序一样对它们进行排序,

  • 例如: éli ->在 E 下
  • ,例如:àli ->在 A 下
  • ,例如:4li -> # 有

什么建议吗?

I have an array of strings (names)

and i would like to sort them like how the address book on the iphone sorts them

  • eg: éli -> under E
  • eg: àli -> under A
  • eg: 4li -> under #

any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情深缘浅 2024-12-03 17:41:02

您需要对字符串执行不区分变音符号的比较。 NSString有一个 compare:options: 方法,其选项为 NSDiacriticInsensitiveSearch

NSArray *array = [NSArray arrayWithObjects:@"éli", @"bob", @"earl", @"allen", @"àli", @"aaron", nil];

NSArray *sorted = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [(NSString*)obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch];
}];

编辑:

这是一个完整的示例,它将根据第一个字符变音符号不敏感来划分结果。我放入了一本字典,因此您需要自己跟踪排序的键才能正确显示。

NSArray *array = [NSArray arrayWithObjects:@"éli", @"bob", @"earl", @"allen", @"àli", nil];

NSArray *sorted = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [(NSString*)obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch];
}];

NSMutableDictionary *sectioned = [NSMutableDictionary dictionary];
NSString *firstChar = nil;

for(NSString *str in sorted)
{
    //Ignore empty strings
    if(![str length])continue;

    NSMutableArray *names = nil;

    //Compare the first character using diacritic insensitive search
    if([str compare:firstChar options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch range:NSMakeRange(0, 1)] == NSOrderedSame)
    {
        names = [sectioned objectForKey:firstChar];
    }
    else
    {
        //decomposedStringWithCanonicalMapping is where the magic happens
        //(it removes the accent mark)
        firstChar = [[str decomposedStringWithCanonicalMapping] substringToIndex:1];
        names = [NSMutableArray array];
        [sectioned setObject:names forKey:firstChar];
    }

    [names addObject:str];
}

NSLog(@"sorted: %@", sorted);
//This is sectioned like the address app
NSLog(@"sectioned: %@", sectioned);

You need to perform a diacritic insensitive comparison against the strings. NSString has a compare:options: method with an option of NSDiacriticInsensitiveSearch.

NSArray *array = [NSArray arrayWithObjects:@"éli", @"bob", @"earl", @"allen", @"àli", @"aaron", nil];

NSArray *sorted = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [(NSString*)obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch];
}];

Edit:

Here is a full example that will section the results based on the first character diacritic insensitive. I put in a dictionary so you would need to keep track of the sorted keys on your own to display properly.

NSArray *array = [NSArray arrayWithObjects:@"éli", @"bob", @"earl", @"allen", @"àli", nil];

NSArray *sorted = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [(NSString*)obj1 compare:obj2 options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch];
}];

NSMutableDictionary *sectioned = [NSMutableDictionary dictionary];
NSString *firstChar = nil;

for(NSString *str in sorted)
{
    //Ignore empty strings
    if(![str length])continue;

    NSMutableArray *names = nil;

    //Compare the first character using diacritic insensitive search
    if([str compare:firstChar options:NSDiacriticInsensitiveSearch|NSCaseInsensitiveSearch range:NSMakeRange(0, 1)] == NSOrderedSame)
    {
        names = [sectioned objectForKey:firstChar];
    }
    else
    {
        //decomposedStringWithCanonicalMapping is where the magic happens
        //(it removes the accent mark)
        firstChar = [[str decomposedStringWithCanonicalMapping] substringToIndex:1];
        names = [NSMutableArray array];
        [sectioned setObject:names forKey:firstChar];
    }

    [names addObject:str];
}

NSLog(@"sorted: %@", sorted);
//This is sectioned like the address app
NSLog(@"sectioned: %@", sectioned);
隐诗 2024-12-03 17:41:02

所有这些都位于 compare: 方法中,您将用作排序方法的选择器,更重要的是使用 NSDiacriticInsensitiveSearch 选项。

[[yourArray] sortedArrayUsingSelector:@selector(compareTheAddressBookWay:)];

现在您需要在类别中添加 compareTheAddressBookWay: 方法

@implementation NSString (YourCategory)

- (NSComparisonResult) compareTheAddressBookWay:(NSString*)iString
{
    return [self compare:iString 
                 options:NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch 
                   range:NSRangeFromString(self)
}

@end

!!Important!!:

使用 sortedArrayUsingSelector: 将兼容 iOS 最高 2.0

使用sortedArrayUsingComparator时:适用于iOS 4及更高版本。

all lies within the compare: method you will use as the selector of your sorting method and more importantly with the NSDiacriticInsensitiveSearch option.

[[yourArray] sortedArrayUsingSelector:@selector(compareTheAddressBookWay:)];

Now you need to add the compareTheAddressBookWay: method in a category

@implementation NSString (YourCategory)

- (NSComparisonResult) compareTheAddressBookWay:(NSString*)iString
{
    return [self compare:iString 
                 options:NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch 
                   range:NSRangeFromString(self)
}

@end

!!Important!!:

Using sortedArrayUsingSelector: will be compliant for iOS up to 2.0

while usingsortedArrayUsingComparator: will ONLY work for iOS 4 and above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文