zoukankan      html  css  js  c++  java
  • 【IOS】将一组包含中文的数据按照#ABC...Z✿分组

    上一篇文章【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:1];
      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, 1)] : [string substringToIndex:1];//取得第一个字母  
        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 = 0; i < indexArray.count; i++) {
      NSMutableArray *alphaArray = [NSMutableArray array];
      for (int j = 0; 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",@"速度与激情",@"1520",@"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

  • 相关阅读:
    x01.Weiqi.6: 立体棋子
    x01.Game.MapEditor: 地图编辑器
    SQL Server插入中文出现乱码??的解决办法
    Cachecontrol使用:header('Cachecontrol:private')
    验证身份证号码Javascript代码
    .Net GDI+缩放绘图
    Access(JETSQL)问题集锦
    Android开发中Google谷歌地图坐标系怎么转Baidu百度地图坐标系
    21、桥接模式(Bridge模式)详解
    22、装饰模式(装饰设计模式)详解
  • 原文地址:https://www.cnblogs.com/yffswyf/p/5542852.html
Copyright © 2011-2022 走看看