上一篇文章【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. XML中的转义字符

    HTML中<, >,&等有特别含义,(前两个字符用于链接签,&用于转义),不能直接使用.使用这三个字符时,应使用他们的转义序列,如下所示: & 或 & &a ...

  2. Linux 信号(二)—— signal 函数

    弗洛伊德认为:要解决这些苦恼,当事人就要通过回忆并理解自己早期的童年经历,来获得对潜意识冲突的顿悟.弗洛伊德的疗法被称为“精神分析” (psychoanalysis),在 20 世纪的很长一段时间被心 ...

  3. SimpleDateFormat使用详解——日期、字符串应用

    public class SimpleDateFormat extends DateFormat SimpleDateFormat 是一个以国别敏感的方式格式化和分析数据的具体类. 它允许格式化 (d ...

  4. underscore 源码解读之 bind 方法的实现

    自从进入七月以来,我的 underscore 源码解读系列 更新缓慢,再这样下去,今年更完的目标似乎要落空,赶紧写一篇压压惊. 前文 跟大家简单介绍了下 ES5 中的 bind 方法以及使用场景(没读 ...

  5. docker 常用命令(*)

    查找镜像 https://hub.docker.com/ search  --> centos7 一般docker 会有一个基础镜像,中间件镜像,应用镜像,生成一个镜像 docker build ...

  6. Bootstap datetimepicker报错TypeError: intermediate value

    Bootstrap datetimepicker有多个版本,官方的链接中,只是datepicker,没有时间的选择,原版的datetimepicker也不再更新,不能用新版的jquery.现在http ...

  7. CentOS升级openssl

    才设置了http2,结果蓝狗说我网站不安全,检测一下发现openssl有漏洞,于是准备升级一下openssl 检测网站: www.ssllabs.com/ssltest/analyze.html # ...

  8. Android 使用代码主动去调用控件的点击事件(模拟人手去触摸控件)

    使用代码主动去调用控件的点击事件(模拟人手去触摸控件) //View 可以是LinearLayout,Button,TextView View.performClick();

  9. 大于16MB的QSPI存放程序引起的ZYNQ重启风险

    ZYNQ芯片是近两年比较流行的片子,双ARM+FPGA,在使用分立FPGA和CPU的场合很容易替代原来的分立器件. ZYNQ可以外接QSPI FLASH作为程序的存储介质. QSPI和SPI flas ...

  10. java-读取javabean中所有属性和属性的类型

    /** * java读取文件中的属性类型 * @param model * @return * @throws Exception */ public static Map<String,Str ...