簡單實現(xiàn)iOS通訊錄拼音分組排序

在實現(xiàn)好友列表或通訊錄功能時窄刘,我們大多需要對名字進行拼音排序及分組蔗怠,后來在網(wǎng)上發(fā)現(xiàn)了YUChineseSorting已經(jīng)實現(xiàn)了基本的字符串排序算法。但是它只能對字符串數(shù)組進行分組排序,并且還需要加入.cpp文件族购,使用比較麻煩攒盈。于是我在原來基礎(chǔ)上對代碼進行封裝抵拘,支持了對對象數(shù)組按對象的某個屬性進行排序。并對原來的代碼進行了合并和封裝型豁,比原來使用更方便僵蛛。

原理

在Objective C語言中,字符串是以unicode進行編碼的迎变。在unicode字符集中充尉,漢字的編碼范圍為4E00(16進制) 到 9FA5(16進制) 之間(即從第19968開始的20902個字符是中文簡體字符)。YUChineseSorting把這些字符的拼音首字母按照原來的順序都存放在一個char數(shù)組中衣形。當我們查找一個漢字的拼音首字母時驼侠,只需把這個漢字的unicode碼(即char強制轉(zhuǎn)換為int)減去19968姿鸿,然后用這個數(shù)字作為索引去找char數(shù)組中存放的字母即可。比較野蠻的一個方法倒源。

調(diào)用方法介紹

首先吧BMChineseSort.h及.m文件導(dǎo)入到項目中苛预,只需要這兩文件。
對自定義對象數(shù)組排序需要只需要使用兩類個方法:

+(NSMutableArray*)IndexWithArray:(NSArray*)objectArray Key:(NSString *)key;
+(NSMutableArray*)sortObjectArray:(NSArray*)objectArray Key:(NSString *)key;

第一個方法:一個參數(shù)objectArray是自定義對象數(shù)組笋熬,另一個參數(shù)key是數(shù)組里需要排序的字段名字热某。方法返回所有出現(xiàn)過的首字母,用于顯示在tableview的head以及右側(cè)索引縮寫胳螟。

第二個方法:昔馋,是根據(jù)對象的某個字段值對整個數(shù)組進行排序,首先旺隙,先將字段首字母拼音相同的對象存到同一個數(shù)組里绒极,然后把所有的數(shù)組再放到結(jié)果數(shù)組里。

獲得的兩個數(shù)組在tableview代理方法中的具體使用可以參考我的demo蔬捷,已上傳到github垄提。

具體tableView設(shè)置

Person對象:
@interface Person : NSObject
@property (strong , nonatomic) NSString * name;
@property (assign , nonatomic) NSInteger number;
@end
通訊錄控制器viewDidLoad方法:
// array是NSArray< Person *>類型的模擬數(shù)據(jù)
self.indexArray = [BMChineseSort IndexWithArray:array Key:@"name"];
self.letterResultArr = [BMChineseSort sortObjectArray:array Key:@"name"];
TableView代理方法:
//section的titleHeader
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    return [self.indexArray objectAtIndex:section];
}
//section行數(shù)
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return [self.indexArray count];
}
//每組section個數(shù)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [[self.letterResultArr objectAtIndex:section] count];
}
//section右側(cè)index數(shù)組
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
    return self.indexArray;
}
//點擊右側(cè)索引表項時調(diào)用 索引與section的對應(yīng)關(guān)系
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{
    return index;
}
//返回cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CELL"];
    if (cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CELL"];
    }
    //獲得對應(yīng)的Person對象
    Person *p = [[self.letterResultArr objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
    cell.textLabel.text = p.name;
    return cell;
}


# 2018.8.3更新v0.2.0

看到還有新同學再用我的庫,所以在看到兩年前的代碼那么丑的情況下周拐,對庫升級維護了下铡俐,整體速度快了1倍以上,具體更改如下:

  • 1.合并IndexWithArray:sortObjectArray:方法妥粟,減少對數(shù)據(jù)的重復(fù)遍歷及轉(zhuǎn)拼音操作導(dǎo)致的時間浪費审丘,新方法為sortWithArray: key: finish:

  • 2.將所有操作放入后臺線程,防止大數(shù)據(jù)時主線程阻塞勾给,通過block回調(diào)拿到數(shù)據(jù)滩报。

  • 3.由于CFStringTransform屬于費時操作,所以在1000條數(shù)據(jù)實驗各種遍歷方法后播急,使用enumerateObjectsWithOptions方法進行多線程遍歷脓钾,進一步降低時間損耗

  • 4.使用BMChineseSortSetting類在外部進行設(shè)置,不需像原來需要修改宏定義桩警,排除一些隱患

  • 4.對于多音字的想了個折中的辦法可训,由于本地判斷無法徹底解決多音字問題,所以在BMChineseSortSetting中通過polyphoneMapping可以手動設(shè)置拼音映射關(guān)系捶枢,現(xiàn)在對于有和預(yù)期不符的拼音可以手動修改啦握截。

    BMChineseSortSetting.share.polyphoneMapping = @{@"重慶":@"CQ"};//單獨對重慶進行映射
    BMChineseSortSetting.share.polyphoneMapping = @{@"長":@"C"};//所有長映射為chang(C)
    
  • 5.將模型排序與字符串排序合并為一個方法,使接口更簡潔烂叔,如果是字符串數(shù)組谨胞,key傳nil即可

新接口使用方法:(具體查看demo)

 [BMChineseSort sortWithArray:array key:@"name" finish:^(bool isSuccess, NSMutableArray<NSString *> *sectionTitleArr, NSMutableArray<NSMutableArray *> *sortedObjArr) {
        if (isSuccess) {
            // tableview reload 
        }
  }];
附:

BMChineseSort使用Demo
IOS數(shù)組按中文關(guān)鍵字以字母序排序

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蒜鸡,隨后出現(xiàn)的幾起案子畜眨,更是在濱河造成了極大的恐慌昼牛,老刑警劉巖术瓮,帶你破解...
    沈念sama閱讀 210,835評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件康聂,死亡現(xiàn)場離奇詭異,居然都是意外死亡胞四,警方通過查閱死者的電腦和手機恬汁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,900評論 2 383
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辜伟,“玉大人氓侧,你說我怎么就攤上這事〉冀疲” “怎么了约巷?”我有些...
    開封第一講書人閱讀 156,481評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長旱捧。 經(jīng)常有香客問我独郎,道長,這世上最難降的妖魔是什么枚赡? 我笑而不...
    開封第一講書人閱讀 56,303評論 1 282
  • 正文 為了忘掉前任氓癌,我火速辦了婚禮,結(jié)果婚禮上贫橙,老公的妹妹穿的比我還像新娘贪婉。我一直安慰自己,他們只是感情好卢肃,可當我...
    茶點故事閱讀 65,375評論 5 384
  • 文/花漫 我一把揭開白布疲迂。 她就那樣靜靜地躺著,像睡著了一般莫湘。 火紅的嫁衣襯著肌膚如雪尤蒿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,729評論 1 289
  • 那天逊脯,我揣著相機與錄音优质,去河邊找鬼。 笑死军洼,一個胖子當著我的面吹牛巩螃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播匕争,決...
    沈念sama閱讀 38,877評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼避乏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了甘桑?” 一聲冷哼從身側(cè)響起拍皮,我...
    開封第一講書人閱讀 37,633評論 0 266
  • 序言:老撾萬榮一對情侶失蹤歹叮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后铆帽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咆耿,經(jīng)...
    沈念sama閱讀 44,088評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,443評論 2 326
  • 正文 我和宋清朗相戀三年爹橱,在試婚紗的時候發(fā)現(xiàn)自己被綠了萨螺。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,563評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡愧驱,死狀恐怖慰技,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情组砚,我是刑警寧澤吻商,帶...
    沈念sama閱讀 34,251評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站糟红,受9級特大地震影響艾帐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜改化,卻給世界環(huán)境...
    茶點故事閱讀 39,827評論 3 312
  • 文/蒙蒙 一掩蛤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陈肛,春花似錦揍鸟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,712評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谈撒,卻和暖如春腥泥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背啃匿。 一陣腳步聲響...
    開封第一講書人閱讀 31,943評論 1 264
  • 我被黑心中介騙來泰國打工蛔外, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人溯乒。 一個月前我還...
    沈念sama閱讀 46,240評論 2 360
  • 正文 我出身青樓夹厌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親裆悄。 傳聞我的和親對象是個殘疾皇子矛纹,可洞房花燭夜當晚...
    茶點故事閱讀 43,435評論 2 348

推薦閱讀更多精彩內(nèi)容