忽略标点符号的排序(Objective-C)

时间:2012-10-24 21:53:34

标签: objective-c sorting

我正在尝试对iOS UITableView对象进行排序。我目前正在使用以下代码:

// Sort terms alphabetically, ignoring case
[self.termsList sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

这对我的清单进行排序,惠斯特无视案例。但是,忽略标点符号也会很好。例如:

c.a.t.
car
cat

应按如下方式排序:

car
c.a.t.
cat

(两只猫(cat或c.a.t.)中的哪一只首先出现,实际上并不重要,只要它们彼此相邻排列。

有没有一种简单的方法来解决这个问题?我认为解决方案将涉及从字符串中提取JUST字母数字字符,然后比较它们,然后将它们返回到以前的状态,并再次包含非字母数字字符。

事实上,我真正关心的唯一字符是句点(。),但是如果有一个解决方案可以轻松涵盖所有标点符号,那么了解它就很有用。

注意:我一个月前问过exact same question of Java。现在,我在Objective-C中创建了相同的解决方案。我想知道iOS API是否有任何技巧可以让这更容易......

编辑:我尝试使用以下代码去除标点符号并填充我排序的另一个数组(由@tiguero建议)。但是,我不知道如何做最后一步:实际按照第二个数组的顺序对第一个数组进行排序。这是我的代码:

    NSMutableArray *arrayWithoutPunctuation = [[NSMutableArray alloc] init];
    for (NSString *item in arrayWithPunctuation)
    {
        // Replace hyphens/periods with spaces
        item = [item stringByReplacingOccurrencesOfString:@"-" withString:@" "]; // ...hyphens
        item = [item stringByReplacingOccurrencesOfString:@"." withString:@" "]; // ...periods
        [arrayWithoutPunctuation addObject:item];
    }
    [arrayWithoutPunctuation sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

这提供了排序的'arrayWithoutPunctuation',但当然不包含标点符号。这并不好,因为虽然它现在排序很好,但它不再包含对数组首先至关重要的标点符号。我需要做的是根据'arrayWithoutPunctuation'的顺序排序'arrayWithPunctuation'...任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:9)

您可以在NSArray上使用比较块,您的代码如下所示:

NSArray* yourStringList = [NSArray arrayWithObjects:@"c.a.t.", @"car", @"cat", nil];
NSArray* yourStringSorted = [yourStringList sortedArrayUsingComparator:^(id a, id b){
        NSString* as = (NSString*)a;
        NSString* bs = (NSString*)b;

        NSCharacterSet *unwantedChars = [NSCharacterSet characterSetWithCharactersInString:@"\\.:',"];
        //Remove unwanted chars
        as = [[as componentsSeparatedByCharactersInSet: unwantedChars] componentsJoinedByString: @""];
        bs = [[as componentsSeparatedByCharactersInSet: unwantedChars] componentsJoinedByString: @""];

        // make the case insensitive comparison btw your two strings
        return [as caseInsensitiveCompare: bs];
    }];

这可能不是最有效的代码,实际上另一个选择是首先迭代你的数组并删除所有不需要的字符并使用selector caseInsensitiveCompare方法:

 NSString* yourStringSorted = [yourStringList sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

答案 1 :(得分:2)

这有点清洁,效率更高:

NSArray* strings = @[@".....c",@"a.",@"a",@"b",@"b...",@"a..,"];
NSArray* sorted_strings = [strings sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    NSString* a = [obj1 stringByTrimmingCharactersInSet:[NSCharacterSet punctuationCharacterSet]];
    NSString* b = [obj2 stringByTrimmingCharactersInSet:[NSCharacterSet punctuationCharacterSet]];
    return [a caseInsensitiveCompare:b];
}];

为了实现真正的效率,我会编写一个忽略标点符号的比较方法,这样就无需进行比较就不需要内存分配。

答案 2 :(得分:1)

我的解决方案是将每个字符串分组到一个具有两个属性

的自定义对象中
  • 原始字符串
  • 没有标点符号的字符串

...然后根据字符串对对象进行排序,不带标点符号。

目标C有一些方便的方法。 所以我们假设我们在这个对象中有两个字符串:

NSString *myString;
NSString *modified;

首先,将自定义对象添加到数组

NSMutableArray *myStrings = [[NSMutableArray alloc] init];
[myStrings addObject: ...];

然后,使用方便的NSSortDescriptor通过 modified 变量对数组进行排序。

//You can specify the variable name to sort by
//Sorting is done according to the locale using localizedStandardCompare
NSSortDescriptor *mySortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"modified" ascending:YES selector:@selector(localizedStandardCompare:)];
[myStrings sortedArrayUsingDescriptors:@[ mySortDescriptor ]];

瞧!您的对象(和字符串)已排序。 For more info on NSSortDescriptor...