上一篇文章【IOS】模仿windowsphone列表索引控件YFMetroListBox里面

我们一步步的实现了WindowsPhone风格的索引。

但是有没有发现,如果你要实现按照字母排序,你还得自己填入这些数据,而不能够让其自动归类。

因此我们这篇文章来说说如何将一个数组进行排序。

标题中的#代表数字、✿代表除了数字、中英文外的其他符号。

1.需求 :将字符串分类成数字、中英文首字母、其他符号三类。

数字、符号按照首字母排序,每一个字母分类中,英文始终在中文前面

这里面主要涉及到了对中文英文进行排序。

2.弯路 :

  1.网络上有一个pinyin.h. 能够获取到中文的首字母,但是仅仅获取到每个字的首字母对我们来说

  还是没有多大用途。  两个首字母相同的中文不知道到底哪个在前,哪个在后。

  2.仅仅是一个中文,并不能够判断其可能是多音字中的哪一个(当然本篇随笔也没有涉及到多音字的处理)

3.储备 :

所以最好的方法就是将中文转换为拼音字符串,然后对字符串排序。

将中文转换为拼音,IOS已经给出了方法了(效率什么的暂时不管)

-(NSString *)transformToPinyin{
NSMutableString *mutableString = [NSMutableString stringWithString:self];  //self指的是该汉字字符串
CFStringTransform((CFMutableStringRef)mutableString, NULL, kCFStringTransformToLatin, false);//带有声调的拼音
CFStringTransform((CFMutableStringRef)mutableString, NULL, kCFStringTransformStripDiacritics, false);//去除声调
return mutableString;
}

利用正则表达式判断字符串的第一位是否是数字、中文、英文

-(BOOL)startWith{
  NSString *firsetStr = [self substringToIndex:];
  NSString *regex = @"[\u4e00-\u9fa5]";//中文 @"[a-zA-Z\\s]"为英文 @"[0-9]"为数字
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
  return [predicate evaluateWithObject:firsetStr];
}

我们分类出来的每一类都是一个数组

可以使用自定义函数sortedArrayUsingFunction进行排序。

[groupedArray addObject:[numberArray sortedArrayUsingFunction:normalSort context:NULL]];

可以通过localizedCompare此方法来进行比较两个字符串

NSInteger normalSort(id string1, id string2, void *context){
NSString *str1 = (NSString *)string1;
NSString *str2 = (NSString *)string2;
NSComparisonResult result = [str1 localizedCompare:(NSString*)str2];return result;
}

4.解决:

现在我们来实现将他们组装成我们在继承UITableView的YFMetroListBox中需要使用的数据。以下均通过静态方法(类方法)获取。

1.IndexArray;  //HeaderView标题数组

- (NSString *)getFirstLetter{
  if([self startWithNumber]){
    return kNumberSign;  //#数字
  }else if([self startWithChinese] || [self startWithEnglish]){
    NSString *string = [self changeToEnglishOrChinese];
    NSString *firstLetter = [string hasPrefix:kDistinguishString] ? [string substringWithRange: NSMakeRange(kDisti    nguishString.length, )] : [string substringToIndex:];//取得第一个字母  
    return firstLetter;
  }else{
  return kSymbolSign;  //✿其他  
  }
}
-(NSString *)changeToEnglishOrChinese{
NSString *alphabet;
if([self startWithChinese]){//1.中文
alphabet= [self transformToPinyin];
}else{//2.英文 增加@"0" kDistinguishString 保证比较的时候比中文首字母小
alphabet = [kDistinguishString stringByAppendingString:self]; }
return alphabet; }

如何保证转换后拼音的拼音与英文比较  英文始终在中文前面?

我是想法是在拼音前加上一小于@"a"的字符: @"0";

在取得标题首字母数组后  就可以和整体(#ABC...Z✿全部)来进行比较,看存在哪些就可以了

2.groupedArray;  //每个分类类别(#.A.B.C...Z.✿)组成的数组

首先通过正则表达式将传入的array分为3大类,数字、中英文(由于英文做了特殊处理,所以可以一起比较了)、其他三大类。

之后对每一类从小到大进行排序。

//给中英文排序
NSArray *indexArray = [self getIndexArray:alphabetArray];//取得IndexArray标题数组
NSArray *headerArray = [self getFirstLetterArray:alphabetArray]; //取得中英文首字母数组
for (int i = ; i < indexArray.count; i++) {
  NSMutableArray *alphaArray = [NSMutableArray array];
  for (int j = ; j < alphabetArray.count; j++) {     
    NSString *headString = headerArray[j];     
    if([[headString uppercaseString] isEqualToString:indexArray[i]]){
      [alphaArray addObject:alphabetArray[j]];     
    }
  }   
   [groupedArray addObject:[alphaArray sortedArrayUsingFunction:cnAndEnSort context:NULL]]; //对每一个数组进行排序
}

3.GroupedDictionaryArray:  //通过上面两部,取得了两组数据,现在可以以字典的形式组装(包含两类)

  1.类似@[{@"indexKey":@"A",@"arrayKey":@[@"abandon",@"啊哈哈",@"All"]}],两个键值对 分别存放标题  和 对应内容数组

  +(NSArray *)getGroupedDictionaryArray:(NSArray *)array;

  2.类似@[{@"A":@[@"abandon",@"啊哈哈",@"All"]}],   一个键值对,key存放标题,value存放对应内容数组

  +(NSArray *)getGroupedDictionaryArray:(NSArray *)array indexKey:(NSString *)indexKey arrayKey:(NSString *)arrayKey;

4.由于本类中很多都是静态方法,内部无法使用非静态方法,并且很多是对NSString字符串的处理,

因为我在本类中写了一个分类,用于字符串的首字母类型判断,截取、转换等操作。

5.成果 :

NSArray *array = [YFGroupedData getGroupedDictionaryArray:[@"Once",@"Begin Again",@"hello wolrd",@"~",@"Windows",@"Lumia",@"苏菲",@"Yvan Wang",@"超能陆战队",@"Angry birds",@")",@"%",@"Windows Phone",@"950XL",@"速度与激情",@"",@"Titanic",@"霸王别姬",@"Captain America",@"World of Warcraft",@"星际穿越",@"反叛的鲁鲁修",@"消失的爱人",@"The Love of Siam",@"荷尔蒙",@"爱·回家",@"7号房的礼物",@"春夏秋冬又一春",@"The Little Prince",@"太阳的后裔",@"非首脑会谈",@"初恋这件小事",@"",@"Baby And Me",@"疯狂动物城",@"Old Boy",@"我的女孩",@"奔跑吧兄弟",@"我滴个神啊"]indexKey:kIndexKey arrayKey:kArrayKey];

来看看部分截图     为空的已经划分为✿部分了。

               

到此完成!

Github:YFGroupedData

【IOS】将一组包含中文的数据按照#ABC...Z✿分组的更多相关文章

  1. python print 打印的数据包含中文,打印报错UnicodeDecodeError: 'gbk' codec can't decode bytes in position 459-460: illegal multibyte sequence解决办法

    python 2.7 print 的数据中若包括中文,打印则会报错UnicodeDecodeError: 'gbk' codec can't decode bytes in position 459- ...

  2. ORACLE判别字段是否包含中文

    在ORACLE数据库中如何查找那些字段里面包含中文的数据记录呢,有时候就是有这样的特殊需求,下面整理了一些判别字段中包含中文记录的几个方法 1:使用ASCIISTR函数判别   ASCIISTR函数说 ...

  3. 生成二维码 加密解密类 TABLE转换成实体、TABLE转换成实体集合(可转换成对象和值类型) COOKIE帮助类 数据类型转换 截取字符串 根据IP获取地点 生成随机字符 UNIX时间转换为DATETIME\DATETIME转换为UNIXTIME 是否包含中文 生成秘钥方式之一 计算某一年 某一周 的起始时间和结束时间

    生成二维码 /// <summary>/// 生成二维码/// </summary>public static class QRcodeUtils{private static ...

  4. 接口测试时如何选择Encoding(针对请求数据内包含中文)

    如果请求数据中包含中文,需要将Encoding选择为utf-8

  5. iOS - 网址、链接、网页地址、下载链接等正则表达式匹配(解决url包含中文不能编码的问题)

    DNS规定,域名中的标号都由英文字母和数字组成,每一个标号不超过63个字符,也不区分大小写字母.标号中除连字符(-)外不能使用其他的标点符号.级别最低的域名写在最左边,而级别最高的域名写在最右边.由多 ...

  6. iOS开发中的4种数据持久化方式【二、数据库 SQLite3、Core Data 的运用】

                   在上文,我们介绍了ios开发中的其中2种数据持久化方式:属性列表.归档解档.本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运 ...

  7. iOS开发中的4种数据持久化方式【一、属性列表与归档解档】

    iOS中的永久存储,也就是在关机重新启动设备,或者关闭应用时,不会丢失数据.在实际开发应用时,往往需要持久存储数据的,这样用户才能在对应用进行操作后,再次启动能看到自己更改的结果与痕迹.ios开发中, ...

  8. 实现textarea限制输入字数(包含中文只能输入10个,全ASCII码能够输入20个)

    document.getElementById("<%=textBox1.ClientID %>").value 实现textarea限制输入字数(包含中文只能输入10 ...

  9. iOS中常用的四种数据持久化方法简介

    iOS中常用的四种数据持久化方法简介 iOS中的数据持久化方式,基本上有以下四种:属性列表.对象归档.SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 ...

随机推荐

  1. SQL Server 修改表结构后无法保存的老问题

    在修改表结构后无法保存,这是每次重装SQL Server后都会遇到的问题,好记性不如烂笔头,在这里记一下吧. 保存修改了的表结构时会提示“不允许保存更改.您所做的更改要求删除并重新创建以下表.您对无法 ...

  2. Java并发包源码分析

    并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互性将大大改善.现代的PC都有多个CPU或一个CPU中有多个 ...

  3. <转>MySQL性能调优的10个方法

    文章原地址:http://mp.weixin.qq.com/s/oRXJRz_Y5drmIrcbxSKOcw 1. 选择合适的存储引擎: InnoDB 除非你的数据表使用来做只读或者全文检索 (相信现 ...

  4. codevs 2830 蓬莱山辉夜

    2830 蓬莱山辉夜 http://codevs.cn/problem/2830/ 题目描述 Description 在幻想乡中,蓬莱山辉夜是月球公主,居住在永远亭上,二次设定说她成天宅在家里玩电脑, ...

  5. mongodb 速成笔记

    以下环境为mac osx + jdk 1.8 + mongodb v3.2.3 一.安装 brew安装方式是mac下最简单的方式 brew update brew install mongodb 其它 ...

  6. 以.net core重构原有.net framework过程中的一些API变更记录(持续更新)

    1)Type.IsGenericType类似属性变更 以下是.net framework 4.5中Type抽象类中泛型类型的几个个属性,用于泛型类型的相关信息判断: 以下是.net core(nets ...

  7. mac 10.11.6 自带apache配置记录

    详细记录使用自带apache的一些问题 开启apache服务 作为2016年的新版本os,在系统偏好设置里没有网络共享了,所以可以通过终端,直接开启apache服务器: 开启apache:sudo a ...

  8. 实用篇!Asp.Net数据传输压缩

    一.业务场景 公司关键业务模块之一考试系统试卷内容加载缓慢.加载失败,前方人员哀声四起,客户投诉,各种爆炸! 二.问题分析 1.试卷存储采用文本文件方式存储 引发问题:并发情况下IO频繁,造成过多的线 ...

  9. Android基础测试题(四)

    看了前两道题大家有没有发现,测试题少了(一),大家猜猜测试题(一)是什么? Android基础测试题(四): 需求: 建一个方法,格式化输出2016-11-14 10:15:26格式的当前时间,然后截 ...

  10. cavans 详解

    http://blog.csdn.net/clh604/article/details/8536059