How do you unfold a nested Julia array?

question

#1

What is an efficient, elegant, Julian way to unfold a nested array:

nested = [[1,2,3],[4,5]]
vcat(nested...) # works but not always

Is there a function in Base to unfold all sorts of nested data structures into a plain list of items?


#2

It sounds like you are looking for Compat.Iterators.flatten (i.e. Base.flatten in 0.5, Base.Iterators.flatten in 0.6).


#3

It seems that flatten() returns an iterator, so you might need collect(flatten()).

Also it seems flatten() works for only 1 nested level.
If you need to flatten deeper nested levels, then something recursive might work:

function unfold(A)
    V = []
    for x in A
        if x === A
            push!(V, x)
        else
            append!(V, unfold(x))
        end
    end
    V
end

Totally untested, but seems to work for the following:

a = ((1,),2)
b = 3:4
c = [5,[6,[7,8]],9]
A = (a,b,c)
unfold(A)

#4

Maybe this?


#5

Thanks @greg_plowman, I marked @fengyang.wang answer as the solution in Base, but it is good to have your solution for multi-level nested structures too.


#6

Thanks @stst, I believe @greg_plowman solution does the same and works for other types other than Arrays.


#7

My way of doing this:

function deepflatten(arr)
    dim = [1]

    function recursiveflatten(arr, dim)
        if isa(arr, Vector{<: Vector})
            recursiveflatten(
                collect(Iterators.flatten(arr)),
                pushfirst!(dim, length(arr) / prod(dim))
            )
        else
            arr, pushfirst!(dim, length(arr) / prod(dim))
        end
    end

    flattened, dim = recursiveflatten(arr, dim)
    reshape(flattened, dim[1:end-1]...)
end