2012-10-24 70 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.」和「貓」是平等的,再次,不像你的代碼,會給兩個不同的權重。 –