Pregunta de entrevista de Meta
Given nested arrays, write an enumerator class such that next() returns the elements in sequential order, e.g.:
[1,[4,3],6,[5,[1,0]]] -> 1, 4, 3, 6, 5, 1, 0
also implement allObjects for this class
Respuestas de entrevistas
[1,[4,3],6,[5,[1,0]]]
-(void)printOutLinearly:(NSArray *)inpA
{
if (!inpA.count) NSLog(@”There’s nothing in this array you silly willy”);
for (int i=0; i < inpA.count; i++)
{
if ([inpA objectAtIndex:i] isKindOfClass:[NSArray class]])
{
[self printOutLinearly:[inpA objectAtIndex:i];
}
else
{
NSLog(@”%@”,[inpA objectAtIndex:i];
}
}
}
Used an array ivar as a stack to maintain state.
func flattenArray(nestedArray: [Any]) -> [Int] {
var myFlattenedArray = [Int]()
for element in nestedArray {
if element is Int {
myFlattenedArray.append(element as! Int)
} else if element is [Any] {
let recursionResult = flattenArray(nestedArray: element as! [Any])
for num in recursionResult {
myFlattenedArray.append(num)
}
}
}
return myFlattenedArray
}
- (void)nestedArray:nestedArray toLinearArray:linearArray
{
for (id item in nestedArray)
{
if ([item isKindOfClass:[NSArray class]])
{
[self nestedArray:item toLinearArray:linearArray];
}
else
{
[linearArray addObject:item];
}
}
}
you can inflate the array in the initializer and maintain a position to use in your next method, and in the allObjects return the inflated array. Otherwise, you can maintain a recursive enumerator as follows (Swift implementation)
class Enumerator{
var pos = 0
var subEnum : Enumerator?
let array : [Any]
init(_ array: [Any])
{
self.array = array
}
func next() -> Int?
{
if subEnum != nil{
if let n = subEnum!.next(){
return n
}else{
subEnum = nil
pos += 1
}
}
if pos == array.count{
return nil
}
let n = array[pos]
if n is [Any]{
subEnum = Enumerator(n as! [Any])
return subEnum!.next()
}
pos += 1
return n as? Int
}
func allObjects() -> [Int]
{
var result = [Int]()
let e = Enumerator(array)
var n = e.next()
while n != nil{
result.append(n!)
n = e.next()
}
return result
}
}
[1,[4,3],6,[5,[1,0]]]
-(NSArray *)enumerateThis:(NSArray *)inpA
{
NSMutableArray *loca = [NSMutableArray new];
if (!inpA.count) return loca;
for (int i=0; i < inpA.count; i++)
{
if ([inpA objectAtIndex:i] isKindOfClass:[NSArray class]])
{
[loca addObjectsFromArray:[self enumerateThis:[inpA objectAtIndex:i]];
}
else
{
[loca addObject:[inpA objectAtIndex:i]];
}
}
return loca;
}
```
class Enumarate {
private var index: Int = 0
var collection: [Any] = []
init?(_ array: [Any]) {
guard array.count != 0 else { return nil}
collection = flatten(array)
}
func next() -> Int {
guard index [Int] {
return collection as! [Int]
}
public func flatten(_ col: [Any]) -> [Int] {
var list = [Int]()
for num in col {
if num is Int {
list.append(num as! Int)
} else if num is [Any] {
let results = flatten(num as! [Any])
for j in results {
list.append(j)
}
}
}
return list
}
}```
final class Enumerator: Sequence, IteratorProtocol, ExpressibleByArrayLiteral {
private let array: [Int]
private var index = 0
init(arrayLiteral elements: [Int]...) {
array = elements.flatMap { $0 }
}
func makeIterator() -> Enumerator {
return Enumerator(arrayLiteral: array)
}
func next() -> Int? {
guard index < array.count else { return nil }
defer { index += 1 }
return array[index]
}
var allObjects: [Int] {
return array
}
let enumerator: Enumerator = [[1], [4,3], [6], [5], [1,0]]