有段时间没写东西了,今天整理了下关于数组、字典、NSSet的遍历,供大家参考。
首先需要注意数组是有序的,字典和set是无序的。
for
for是最基本的循环方法,也是初学者用的最多的循环方法了。
NSArray * arr = @[...];
for (int i = 0; i < arr.count; i++) {
id obj = arr[i];
....
}
NSDictionary * dict =@{...};
NSArray * keys = [dict allKeys];
for (int i = 0; i < keys.count; i++) {
id key = key[i];
id value = dict[key];
...
}
NSSet * aSet = (NSSet *)@[...];
NSArray * objects = [aSet allObjects];
for (int i = 0; i < objects.count; i++) {
id object = objects[i];
...
}
for循环可正反遍历,可从中间开始遍历,可获取元素对应下标(字典和set无序故下标无意义),缺点是效率低,且遍历字典和set的时候还需要引入中介数组。
NSEnumerator(Objective-C 1.0)
NSEnumeratro 主要调用- (id)nextObject这个方法,它返回枚举里的下一个对象。当下一个调用返回为nil的时候,就表示遍历结束了。
NSArray * arr = @[...];
NSEnumerator * enumerator = [arr objectEnumerator];
//换成NSEnumerator * enumerator =[arr reverseObjectEnumerator]则为反向遍历
id object;
while (object = [enumerator nextObject]) {
...
}
NSDictionary * dict = @{...};
NSEnumerator * enumerator = [dict keyEnumerator];
id key;
while ((key = [enumerator nextObject]) != nil) {
id value = dict[key];
...
}
NSSet * aSet = (NSSet *)@[...];
NSEnumerator * enumerator = [aSet objectEnumerator];
id object;
while ((object = [enumerator nextObject]) != nil) {
...
}
for-in (Objective-C 2.0)
NSArray * arr = @[...];
for (id object in arr) {
...此为正向遍历
}
for (id object in [arr reverseObjectEnumerator]) {
...此为反向遍历
}
NSDictionary * dict = @{...};
for (id key in dict) {
id value = dict[key]
}
NSSet * aSet = (NSSet *)@[...];
for (id object in aSet) {
...
}
for-in的效率高于for 和 NSEnumerator,缺点是无法获取元素下标。
block
NSArray * arr = @[...];
[arr enumerateObjectsUsingBlock:^(id _Nonnull obj, BOOL * _Nonnull stop) {//正向遍历
...
if (...){
*stop = YES;//遍历停止
}
}];
[arr enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {//反向遍历
...
if (...) {
*stop = YES;
}
}];
NSDictionary * dict = @{...};
[dict enumerateKeysAndObjectsUsingBlock:^(id key,id object,BOOL * stop) {
...
if (...) {
*stop = YES;
}
}];
NSSet * aSet = (NSSet *)@[...];
[aSet enumerateObjectsUsingBlock:^(id _Nonnull obj, BOOL * _Nonnull stop) {
...
if (...) {
*stop = YES;
}
}];
此方法高效、可随时停止遍历,可获取下标,缺点是没有for-in简洁,根据需要选取相应的遍历方式即可。