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?

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?

1 Like

It sounds like you are looking for `Compat.Iterators.flatten`

(i.e. `Base.flatten`

in 0.5, `Base.Iterators.flatten`

in 0.6).

4 Likes

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)
```

3 Likes

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.

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

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
```

1 Like

For arbitrary nesting like `x = [[1,2], [3, [4, [5]]]]`

, what I ended up doing was

```
using AbstractTrees
x = [[1, 2], [3, [4, [5]]]]
v = collect(Leaves(x)) # [1, 2, 3, 4, 5]
```

In Rosetta code there is a fast solution:

```
flat(arr) = mapreduce(x -> x == [] || x[1] === x ? x : flat(x), vcat, arr, init=[])
x = [[1,2], [3, [4, [5]]]]
y = ((1,2), (3, (4, (5))))
z = (((1,),2), 3:4, [5,[6,[7,8]],9])
w = (("ab", 'c'), 1:3)
flat(x)
flat(y)
flat(z)
flat(w)
```

```
using IterTools
flatn(w)=collect(nth(iterated(Base.Flatten,w),length(split(string(w),['[','(']))))
```

If you have a nested Tuple, where all elements are values or Tuples (not vectors),

this is a performant and memory respectful solution. As written, it returns a Vector. To obtain a tuple, use

`result = Tuple(flattener(nestedtuples))`

```
using TupleTools
function flattener(x)
y = TupleTools.flatten(x)
n = sum(length.(y))
z = Vector{Any}(undef, n)
i=1; for k in y
if isa(k, Tuple)
for r in k
z[i] = r
end
else
z[i] = k
end
i += 1
end
z
end
```

1 Like

if I understand correctly this function is based on something like the following.

Why can’t it also apply to generic vectors?

```
flat(x::Any)=(x,)
flat(t::Tuple{}) = ()
flat(t::Tuple)=(flat(t[1])...,flat(Base.tail(t))...)
```

this one (which I’ve come to by trial and error) seems to work for nested vectors.

I have tried in vain to reproduce a method for dispatching on empty vectors in a way equivalent to that for empty tuples.

```
flav(x::Union{Real, String, Char})=x
flav(v :: AbstractArray)=[flav(v[1])...,(isempty(v[2:end]) ? [] : flav(v[2:end]))...]
v=[1.,'b']
v1=[11,v]
flav(v1)
v2=[[1,"abc"],v1]
v3=[[3,[31,32]],v2]
flav(v3)
v4=[v2,[v1,v3]]
flav(v4)
```