2012-10-24 71 views
8

我想排序iOS UITableView对象。我目前使用下面的代码:排序忽略标点符号(Objective-C)

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

这个排序名单,惠斯特忽略大小写。但是,忽略标点符号也会很好。例如:

car 
c.a.t. 
cat 

(实际上它并不无论哪两只猫(猫或猫)的至上,只要他们进行排序:

c.a.t. 
car 
cat 

应如下排序彼此相邻)。

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

事实上,我真正关心的唯一字符是句点(。),但是如果有一种方法可以很容易地覆盖所有标点符号,那么知道它会很有用。

注:我在一个月前询问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'...任何帮助表示赞赏。

+1

只需使用自定义比较器即可。 –

+0

我的回答无效吗? – tiguero

+0

至今我还没有能够实现它。我会接受一次,我可以得到它的工作 – CaptainProg

回答

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]; 
    }]; 

这可能不是最有效的代码实际上是另外一个选择是首先你的阵列上进行迭代,并删除所有不必要的字符,并使用selectorcaseInsensitiveCompare方法:

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

我一直在为此奋斗了很多天。我试图实施你的第二个建议(我无法实现第一个建议);请看我的编辑到我的文章! – CaptainProg

+4

@CaptainProg:tiguero的第一个建议将会实现你想要的。 –

+0

正如@iMoses所做的那样,这对我的设置不起作用。我不知道为什么,但是完全停止的字符串仍然保持在没有的情况下,无论我使用哪种解决方案......这肯定是由这段代码引起的,因为它只发生在我尝试一种排序算法(任何类型)之后发生, 。所以排序(某种)正在发生。将尝试深入挖掘,但赏金可能会在我找到原因之前到期 – CaptainProg

1

我的解决办法是组中的每个字符串转换成自定义对象与正确领带

  • 原始字符串
  • 串不加标点

...,然后根据不加标点的字符串对象进行排序。目标C有一些方便的方法来做到这一点。 所以我们可以说,我们在这个对象两个字符串:

NSString *myString; 
NSString *modified; 

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

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

然后,使用得心应手NSSortDescriptor由修改变量数组排序。

//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...

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]; 
}]; 

对于真正的效率,我会写一个比较忽略标点符号方法,所以没有内存分配将需要只是为了比较。

+0

这个代码,就像Tiguero的第一个代码一样,仍然使用连字符排序,将试图找出如何,但它看起来像赏金将首先到期 – CaptainProg

+0

我已检查它,它适用于我,使用这个数组,@ [@“..... c”,@“a”,@ “a。”,@“b”,@“b ...”,@“a ..,”];它给,( 一, “一个。”, “一..”, B, “B ......”, “..... C” ) – iDev

+0

@CaptainProg,这个代码(和@ tiguero的)工作得很好。无论你的问题是误导还是你错过了其他的东西。与您的排序方法不同 - 它不会用空格替换标点符号,以便“c.a.t.”和“猫”是平等的,再次,不像你的代码,会给两个不同的权重。 –