-
-
Save tangqiaoboy/452e106e0472b9e90cf17de180b6d211 to your computer and use it in GitHub Desktop.
给你一个嵌套的 NSArray 数据,实现一个迭代器类,该类提供一个 next() 方法,可以依次的取出这个 NSArray 中的数据。 比如 NSArray 如果是 `[1,[4,3],6,[5,[1,0]]]`, 则最终应该输出:`1, 4, 3, 6, 5, 1, 0` 。 另外,实现一个 `allObjects` 方法,可以一次性取出所有元素。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AlgorithmSolutionCode | |
// | |
// Created by TangQiao on 12/13/16. | |
// Copyright © 2016 Tang Qiao. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
@interface NSArrayIterator : NSObject | |
- (id)initWithArray:(NSArray *)array; | |
- (id)next; | |
- (NSArray *)allObjects; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AlgorithmSolutionCode | |
// | |
// Created by TangQiao on 12/13/16. | |
// Copyright © 2016 Tang Qiao. All rights reserved. | |
// | |
#import "NSArrayIterator.h" | |
@interface NSArrayIteratorCursor : NSObject | |
@property (nonatomic) NSArray *array; | |
@property (nonatomic) NSUInteger index; | |
@end | |
@implementation NSArrayIteratorCursor | |
- (id)initWithArray:(NSArray *)array { | |
self = [super init]; | |
if (self) { | |
_array = array; | |
_index = 0; | |
} | |
return self; | |
} | |
@end | |
@implementation NSArrayIterator { | |
NSMutableArray *_stack; | |
NSArray *_originArray; | |
} | |
- (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]; | |
} | |
- (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) { | |
return nil; | |
} | |
// 4. 终于拿到元素了,这一步判断拿到的元素是否是数组。 | |
id item = c.array[c.index]; | |
if ([item isKindOfClass:[NSArray class]]) { | |
c.index++; | |
// 5. 如果是数组,则重新生成一个遍历的 | |
// NSArrayIteratorCursor 对象,放到栈中, 然后递归调用 next 方法 | |
[self setupStackWithArray:item]; | |
return [self next]; | |
} | |
// 6. 如果到了这一步,说明拿到了一个非数组的元素,这样就可以把元素返回, | |
// 同时更新索引到下一个位置。 | |
c.index++; | |
return item; | |
} | |
- (NSArray *)allObjects { | |
NSMutableArray *result = [NSMutableArray array]; | |
[self fillArray:_originArray into:result]; | |
return result; | |
} | |
- (void)fillArray:(NSArray *)array into:(NSMutableArray *)result { | |
for (id item in array) { | |
if ([item isKindOfClass:[NSArray class]]) { | |
[self fillArray:item into:result]; | |
} else { | |
[result addObject:item]; | |
} | |
} | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NSArrayIteratorTest.m | |
// AlgorithmSolutionCode | |
// | |
// Created by TangQiao on 12/13/16. | |
// Copyright © 2016 Tang Qiao. All rights reserved. | |
// | |
#import <XCTest/XCTest.h> | |
#import "NSArrayIterator.h" | |
@interface NSArrayIteratorTest : XCTestCase | |
@end | |
@implementation NSArrayIteratorTest | |
- (void)testNext { | |
NSArray *arr = @[@1, @2, @[ @[ @5], @3, @4], @[@6, @7, @[ @[ @[ @8 ]]]]]; | |
NSArrayIterator *c = [[NSArrayIterator alloc] initWithArray:arr]; | |
XCTAssertEqualObjects(@1, [c next]); | |
XCTAssertEqualObjects(@2, [c next]); | |
XCTAssertEqualObjects(@5, [c next]); | |
XCTAssertEqualObjects(@3, [c next]); | |
XCTAssertEqualObjects(@4, [c next]); | |
XCTAssertEqualObjects(@6, [c next]); | |
XCTAssertEqualObjects(@7, [c next]); | |
XCTAssertEqualObjects(@8, [c next]); | |
XCTAssertEqualObjects(nil, [c next]); | |
XCTAssertEqualObjects(nil, [c next]); | |
} | |
- (void)testEmptyNestedArray { | |
NSArray *arr = @[@1, @2, @[ @[ ], @3, @4, @[]], @[@6, @7, @[ @[ @[ @8 ]]]]]; | |
NSArrayIterator *c = [[NSArrayIterator alloc] initWithArray:arr]; | |
XCTAssertEqualObjects(@1, [c next]); | |
XCTAssertEqualObjects(@2, [c next]); | |
XCTAssertEqualObjects(@3, [c next]); | |
XCTAssertEqualObjects(@4, [c next]); | |
XCTAssertEqualObjects(@6, [c next]); | |
XCTAssertEqualObjects(@7, [c next]); | |
XCTAssertEqualObjects(@8, [c next]); | |
XCTAssertEqualObjects(nil, [c next]); | |
XCTAssertEqualObjects(nil, [c next]); | |
} | |
- (void)testEmptyArray { | |
NSArray *arr = @[ @[ @[ ]], @[@[ @[ @[ ]]]]]; | |
NSArrayIterator *c = [[NSArrayIterator alloc] initWithArray:arr]; | |
XCTAssertEqualObjects(nil, [c next]); | |
XCTAssertEqualObjects(nil, [c next]); | |
} | |
- (void)testAllObjects { | |
NSArray *arr = @[@1, @2, @[ @[ @5], @3, @4], @[@6, @7, @[ @[ @[ @8 ]]]]]; | |
NSArray *expect = @[@1, @2, @5, @3, @4, @6, @7, @8]; | |
NSArrayIterator *c = [[NSArrayIterator alloc] initWithArray:arr]; | |
XCTAssertEqualObjects(expect, [c allObjects]); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
我觉得在初始化时 就调用
fillArray
来获得一个 flatArray .然后.
next() 就简单了.