Challenge: solve Flatten Array without recursing

Use whatever language you like! Enjoy :smiley:

I’m curious to see how various languages allow one to express solutions to this problem.

I will post solutions of my own later.

This solution mutates the input. Python, nine lines.

Python Flatten
def flatten(val):                                                                                                                               
    out = []                                                                                                                                    
    while val:                                                                                                                                  
        item = val.pop()                                                                                                                        
        if isinstance(item, list):                                                                                                              
            val.extend(item)                                                                                                                    
        elif item is not None:                                                                                                                  
            out.append(item)                                                                                                                    
    return list(reversed(out))
2 Likes

Pure function; the only memory use is in the output and the stack of iterators (which does not grow past the original nesting depth).

Python
def flatten(iterable):
    stack = [iter(iterable)]
    result = []
    while stack:
        for e in stack[-1]:
            if isinstance(e, Iterable) and not isinstance(e, str):
                stack.append(iter(e))
                break
            if e is not None:
                result.append(e)
        else:
            stack.pop()
    return result

My first attempt was just like MatthijsBlom’s stack idea, but after seeing IsaacG’s implicit stack, I came up with this:

Python
from collections.abc import Iterable
from itertools import chain

def flatten(iterable):
    result = []
    absent = object()
    producer = iter(iterable)
    while (val := next(producer, absent)) is not absent:
        if isinstance(val, Iterable):
            producer = chain(val, producer)
        elif val is not None:
            result.append(val)

    return result

Unfortunately I couldn’t find a nicer way to iterate without try/except StopIteration. I woud appreciate any help from someone more experienced on how to clean it up.

UPD: Thanks to MatthijsBlom for suggestions on how to improve the original version.

That’s a great solution! I hadn’t thought to work on it in place during my turn. Thank you!