10.11 可变数组 和 字符串类方法练习

//10.11: NSMutableArray类中常用方法练习

+ (void)nsMutableArrayTest

{

    //NSMutableArray是NSArray的子类,所以NSArray的功能它全部都可以使用,并且NSMutableArray对象是可变的。即对象创建了之后,也可以删除和添加元素,也可以替换元素。

    NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"james", @"wade", @"bosh", nil];

   

    NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSetWithIndex:4];

    [indexSet addIndex:0];

    [indexSet addIndex:2];

    [indexSet addIndex:0];

    NSLog(@"set: %@", indexSet); //将打印0,2,4;表示set集合是有序的,并且元素是唯一的。set集合会自动移除相等的元素只留下一个。用isEqual判别两个元素是否相等;

   

//一、添加、删除、替换元素方法

    //0.添加一个对象

    [mutableArray addObject:@"allen"];

    //1.在指定索引处插入对象, 会导致元素后移。

    [mutableArray insertObject:@"Howard" atIndex:3];

    //2.在指定的索引集合中按大小排列的索引处插入另一个数组中按前后顺序排列的元素。

    NSArray *arr = @[@"0", @"2", @"4"];

    [mutableArray insertObjects:arr atIndexes:indexSet];

   

    //3.移除最后一个元素

    [mutableArray removeLastObject];

    //4.移除指定索引处的元素

    [mutableArray removeObjectAtIndex:3];

    //5.移除和指定对象匹配的所有元素, 若没有与该对象匹配的元素,将不做任何操作;该方法给每个元素发送isEqual:消息,并利用indexOfObject:获得匹配的元素的索引,再利用removeObjectAtIndex:方法将该元素移除。

    [mutableArray removeObject:@"bosh1"];

    //6.移除数组中一定范围内的和指定对象匹配的所有元素。

    //removeObject: inRange:

    //7. 移除和指定对象匹配的所有元素,不过匹配方式更严格,要求元素和指定对象的地址要相等。

    [mutableArray removeObjectIdenticalTo:@"bosh2"];

    //8. 移除一定范围内和指定对象地址相等的所有元素。

    //removeObjectIdenticalTo: inRange:

    //9.从数组中移除和另一个数组中相等的元素,该方法需要另一个数组中的所有元素都能响应isEqual: 和 hash方法。该方法只会移除本数组中和另一个数组中相等的元素,对于不包含的元素,没有作用。

    NSArray *array = @[@"James", @"Wade", @"Bosh", @"Howard", @"Irving"];

    [mutableArray removeObjectsInArray:array];

    //10. 移除一定范围内的所有元素, 该方法的实现用到了removeObjectAtIndex;

    [mutableArray removeObjectsInRange:NSMakeRange(1, 2)];

    //11.移除所有元素

    [mutableArray removeAllObjects];

    //12.移除指定索引集合中包含的所有索引处的元素。

    //- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;

   

    //13.将另外一个数组中的所有元素添加到本数组末尾。

    [mutableArray addObjectsFromArray:array];

   

    //14.替换指定索引处的元素

    [mutableArray replaceObjectAtIndex:3 withObject:@"allen"];

    //15.用另一个数组中指定范围otherRange内的元素替换本数组中指定范围range内的元素。如果otherRange > range,则将otherRange多出的元素插入到本数组中,否则,移除range范围内多出的对象。如果不指定otherRange参数,则相当于otherRange为0~[otherArray count]-1;

    [mutableArray replaceObjectsInRange:NSMakeRange(1, 2) withObjectsFromArray:array range:NSMakeRange(1, 3)];

    //16.用另一个数组中的元素按前后顺序替换本数组中指定索引集合中的按大小顺序排列的各个索引处的元素。如果这另一个数组的元素个数小于索引集合中的索引数,将报错。

    [mutableArray replaceObjectsAtIndexes:indexSet withObjects:arr];

    //17.将本数组替换成另一个数组相等。

    [mutableArray setArray:array];

    //18. 将指定索引处的元素替换成指定对象,如果指定索引值等于数组的元素个数,将指定对象添加到数组的末尾,并使数组元素个数加一。但如果索引值大于元素个数,报错。

    [mutableArray setObject:@"haha" atIndexedSubscript:5];

    NSLog(@"%@", mutableArray);

   

//二、可变数组创建,初始化类别(NSMutableArrayCreation)

    //1.给可变数组对象分配指定的空间进行初始化,这个指定的空间大小并不是可变数组对象的最终大小,只是该方法执行完后会分配这个大小的空间。以后可变数组的大小可以增长。

    NSMutableArray *mutableArrayInit = [NSMutableArray arrayWithCapacity:10];

    //2.所有NSArray的创建和初始化都可以用。如arrayWithObjects,initWithObjects。arrayWithArray,initWithArray....

    [mutableArrayInit addObjectsFromArray:array];

   

//三、给可变数组对象排序

    //1.利用block对象比较器给可变数组排序,该方法将直接影响本可变数组对象。而NSArray的sortedArrayUsingComparator: 及其一类的方法都会返回一个排好序的新数组,方法不影响原数组对象。因为NSArray对象是不可变的。而NSMutableArray的这类排序方法的返回值都是void,直接影响原数组对象。还可以指定排序的选项,NSSortConcurrent选项表示并发,NSSortStable表示排序是稳定的。

    NSLog(@"sort before: \n%@", mutableArray);

    [mutableArray sortWithOptions:NSSortStable usingComparator:^(NSString *str1, NSString *str2){

        return [str1 compare:str2];

    }];

   

    //2.利用C语言中的函数指针指向的函数作为比较器给可变数组对象排序。

    //- (void)sortUsingFunction:(NSInteger (*)(id, id, void *))compare context:(void *)context;

   

    //3.利用选择器参数指向的方法作为比较器给数组排序。

    //- (void)sortUsingSelector:(SEL)comparator;

   

    NSLog(@"sort after: \n%@", mutableArray);

}

 //字符串类型方法练习

+ (void)nsStringTest

{

    //NSString指不可变的OC字符串,即一旦创建和初始化后就不能修改。

    NSString *string;

//一、创建,初始化字符串

    //1.用另一个字符串直接初始化。

    string = @"abc";

    //2.用指定的格式字符串初始化

    string = [NSString stringWithFormat:@"%@ is a string", @"this"];

    //3.用指定编码方式编码后的数据块初始化

    //- (instancetype)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding;

    //4.用指定编码方式编码后的指定长度的缓冲区中的内容初始化;

    const char *bytes = "I am a string";

    string = [[NSString alloc] initWithBytes:bytes length: strlen(bytes) + 1 encoding:1];

    //5. 从文件中读取, 这个是关于属性列表的学习。

    //- (instancetype)initWithContentsOfFile:(NSString *)path usedEncoding:(NSStringEncoding *)enc error:(NSError **)error;

    //+ (instancetype)stringWithContentsOfFile:(NSString *)path usedEncoding:(NSStringEncoding *)enc error:(NSError **)error;

    //6. 从URL中读取

    //- (instancetype)initWithContentsOfURL:(NSURL *)url usedEncoding:(NSStringEncoding *)enc error:(NSError **)error;

    //+ (instancetype)stringWithContentsOfURL:(NSURL *)url usedEncoding:(NSStringEncoding *)enc error:(NSError **)error;

    //7. 写入文件

    //- (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;

    //8.写入URL

    //- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;

 

   

//二、字符串的长度属性length 和获取长度的方法 length

    NSLog(@"length:%lu, %lu", string.length, [string length]);

   

//三、获取子字符串操作

    //1.获取指定索引处的单个字符。

    unichar ch = [string characterAtIndex:0]; //unichar是unsigned short类型;

    //2.获取一定范围内的所有字符到指定的c语言数组缓冲区中

    unichar chs[15] ;

    [string getCharacters:chs range:NSMakeRange(0, 5)];

    //3.获取从指定索引开始到结束的子字符串,包含指定索引处字符

    string = [string substringFromIndex:0];

    //4.获取从开始到指定索引处的子字符串, 不包括指定索引处的字符

    string = [string substringToIndex:string.length];

    //5.获取一定范围内的子字符串, 范围边界的字符含前不含尾;

    string = [string substringWithRange:NSMakeRange(0, string.length)];

   

//四、字符串比较操作

    //1. 该方法将本字符串中指定范围内的子字符串 同 指定的字符串按 指定的选项 指示的方法比较,采用逐个字符比较,按词典中的字符前后顺序(大写在前,小写在后)排序。选项中可以设置不关心大小写(NSCaseInsensitiveSearch),只比较字符串的数据值(NSNumericSearch),完全比较,关心大小写(NSLiteralSearch)等等;返回值为-1,表示本字符串小于指定的字符串。返回值为0,表示两个字符串的内容和属性都相同。

    string = @"I am a string";

    NSComparisonResult result = [string compare:@"i am a string" options:NSLiteralSearch range:NSMakeRange(0, string.length)];

    NSLog(@"%ld", result);

    //2. 该方法判别两个字符串对象是否相等.

    //isEqualToString方法的参数是字符串,如果不是,报无效参数异常。该方法首先查看两个字符串的地址是否一样,一样,直接返回YES,不一样再判断两个字符串的内容和属性是否一样。一样,返回YES,否则返回NO。

    //isEqual:方法首先判断两个对象的地址是否一样,一样,直接返回YES;不一样,再看两者是否是同一个类型,如果不是同一类型,直接返回NO;是同一类型,再看两个对象的属性和数据是否一样,一样,返回YES。

    //相等的两个对象有相同的hash值,但是有相同的hash值的对象不一定相等;特别记住这一点;一般如果一个对象存放在set集合中,则这个对象需要重写hash方法,因为set集合是没有相同的元素的。

    NSLog(@"isEqualToString: %d", [string isEqualToString:@"I am a string"]);

    //3.判别一个字符串是否以指定的字符串开头

    NSLog(@"hasPrefix: %d", [string hasPrefix:@"I m"]);

    //4.判别一个字符串是否以指定的字符串结束

    NSLog(@"hasSuffix: %d", [string hasSuffix:@"string"]);

    //5.在本字符串string对象中的指定范围searchRange中,按选项参数options 和local参数 指定的方式查找指定字符串aString的索引范围.可以不指定搜索范围searchRange,选项options,local;

    //rangeOfString: aString options:mask range: searchRange locale:locale

   

    //6.这里要知道NSString和Unicode编码之间的联系才好理解。

    /*NSString是UTF-16编码的,也就是16位的unichar字符的序列,所以,一般的遍历一个字符串中的每一个字符的形式如下:

     for(int i = 0; i < str.length; i++){

        unichar ch = [str characterAtIndex: i];

     }

     但是,平时我们书写的字符,并不全都是用唯一的一个16位字符来表示,而是有一部分字符用两个16位字符来表示。这就是surrogate pairs的概念,如果还是用上面的方式来遍历的话,就会出现“断字”;例如Apple Color Emoji字体集中的“THUMBS UP SIGN”(竖大拇指👍)字符,其实就是用2个16位unichar来表示,它的Unicode码点是U+1F44D,用(U+D83D U+DC4D)两个字符来表示。

     还好,NSString的rangeOfComposedCharacterSequencesForRange: 和rangeOfComposedCharacterSequenceAtIndex:方法可以用来处理这中情况,所以正确的遍历NSString的每一个字符的方法就是下面这样:

     NSRange range;

     for(int i = 0; i < str.length; i += range.length){

        range = [str rangeOfComposedCharacterSequenceAtIndex: i];

        NSString *s = [str attributedSubstringFromRange:range]

     }

     一次遍历的是一个子串,而不是遍历一个unichar了;

     */

    string = @"there have a 🐎 named horse";

    NSRange range1 = [string rangeOfComposedCharacterSequenceAtIndex:13];

    NSLog(@"%lu, %lu", range1.location, range1.length);

    NSRange range2 = [string rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, 14)];//由此可以看出‘🐎’是由2个16位unichar字符组成的。

    NSLog(@"%lu, %lu", range2.location, range2.length);

    NSLog(@"%lu", string.length);//输出27. 表示字符串的length属性是以字符串中包含的16位unichar字符个数决定的。

   

//五、追加字符串,注意这里不是修改了原字符串对象,而是将先复制一分原对象的内容再在末尾添加字符串然后返回赋值给一个新的字符串对象。原字符串对象并没有修改。该新的字符串对象的地址和原对象地址不一样;

    //1. 直接追加一个字符串

    NSString *string1 = [string stringByAppendingString:@"!!!"];

    //2. 用格式化参数形式追加一个字符串

    NSString *string2 = [string stringByAppendingFormat:@" it's age is %d.", 5];

    NSLog(@"<%p>, <%p>, <%p>", string1, string2, string);

   

//六、字符串转化为数值, 转换时一旦碰到不是数字的字符(不包括+,-,.),就停止转换,返回之前转换的结果。如果第一个字符不是数字,结果为0;这些方法都会忽略字符串最前面的空格;

    string = @"  123.456";

    //1.转换为double型;

    NSLog(@"\ndoubleValue: %f", [string doubleValue]);

    //2.转换为float类型

    NSLog(@"floatValue: %f", [string floatValue]);

    //3.转换为int型

    NSLog(@"intValue: %d", [string intValue]);

    //4.转换为NSInteger型

    NSLog(@"NSInteger: %ld", [string integerValue]);

    //5.转换为longlong型

    NSLog(@"longlong: %lld", [string longLongValue]);

    //6.转换为BOOL类型

    NSLog(@"bool: %d", [string boolValue]);

   

    //NSLog(@"%@", string);

}

posted @ 2014-10-19 22:57  _蚕豆_  阅读(417)  评论(0)    收藏  举报