昨天我的代碼,有一個 Bug,就是我沒有處理好嵌套的數(shù)組元素為空的情況,我寫了一個簡單的 TestCase,大家也可以試試自己的代碼是否處理好了這種情況:
- (void)testEmptyArray {
NSArray *arr = @[ @[ @[ ]], @[@[ @[ @[ ]]]]];
NSArrayIterator *c =[[NSArrayIterator alloc]initWithArray:arr];
XCTAssertEqualObjects(nil,[c next]);
XCTAssertEqualObjects(nil,[c next]);
}
于是乎,我發(fā)現(xiàn)我的代碼可以再優(yōu)化一下,用遞歸的方式來處理空數(shù)組的邏輯似乎是寫起來更簡單的,于是我優(yōu)化之后的邏輯如下:
判斷棧是否為空,如果為空則返回 nil。
從棧中取出元素,看是否遍歷到了結尾,如果是的話,則出棧。
判斷第 2 步是否使棧為空,如果為空,則返回 nil。
終于拿到元素了,這一步判斷拿到的元素是否是數(shù)組。
如果是數(shù)組,則重新生成一個遍歷的 NSArrayIteratorCursor 對象,放到棧中,并且遞歸調用自己。
如果不是數(shù)組,就把元素返回,同時更新索引到下一個位置。
整個代碼也變得更短更清楚了一些,如下所示:
next 方法的實現(xiàn):
- (id)next {
//? 1. 判斷棧是否為空,如果為空則返回 nil。
if(_stack.count==0) {
return ?nil;
}
// 2. 從棧中取出元素,看是否遍歷到了結尾,如果是的話,則出棧。
NSArrayIteratorCursor *c;
c= [_stack lastObject];
while(c.index ==c.array.count&& _stack.count>0) {
[_stack removeLastObject];
c= [_stack lastObject];
}
// 3. 判斷第2步是否使棧為空,如果為空,則返回 nil。
if(_stack.count==0) {
returnnil;
}
// 4. 終于拿到元素了,這一步判斷拿到的元素是否是數(shù)組。
id item =c.array[c.index];
if([item isKindOfClass:[NSArrayclass]]){
c.index++;
// 5. 如果是數(shù)組,則重新生成一個遍歷的
//? ? NSArrayIteratorCursor 對象,放到棧中, 然后遞歸調用 next 方法
[self setupStackWithArray:item];
return[self next];
}
// 6. 如果到了這一步,說明拿到了一個非數(shù)組的元素,這樣就可以把元素返回,
//? ? 同時更新索引到下一個位置。
c.index++;
?return ?item;
}
初使化部分:
- (id)initWithArray:(NSArray*)array {
self= [super init];
if(self) {
_originArray = array;
_stack = [NSMutableArray array];
[self setupStackWithArray:array];
}
return self;
}
- (void)setupStackWithArray:(NSArray*)array?
{NSArrayIteratorCursor *c= [[NSArrayIteratorCursor alloc] initWithArray:array];
[_stack addObject:c];
}
}