昨天我的代碼,有一個 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找默。
從棧中取出元素,看是否遍歷到了結(jié)尾场靴,如果是的話啡莉,則出棧港准。
判斷第 2 步是否使棧為空,如果為空咧欣,則返回 nil浅缸。
終于拿到元素了,這一步判斷拿到的元素是否是數(shù)組魄咕。
如果是數(shù)組衩椒,則重新生成一個遍歷的 NSArrayIteratorCursor 對象,放到棧中哮兰,并且遞歸調(diào)用自己毛萌。
如果不是數(shù)組,就把元素返回喝滞,同時更新索引到下一個位置阁将。
整個代碼也變得更短更清楚了一些,如下所示:
next 方法的實現(xiàn):
- (id)next {
//? 1. 判斷棧是否為空右遭,如果為空則返回 nil做盅。
if(_stack.count==0) {
return ?nil;
}
// 2. 從棧中取出元素,看是否遍歷到了結(jié)尾窘哈,如果是的話吹榴,則出棧。
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 對象哨鸭,放到棧中, 然后遞歸調(diào)用 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];
}
}