Iteration over collections with unassigned entries

How does one handle #undef entries in a comprehension over a collection?

Say I have

julia> struct Foo
           v::Vector{Int}
       end

julia> bar = Vector{Foo}(uninitialized, 3); bar[1] = Foo([1]); bar[3] = Foo([3,4]);

julia> bar
3-element Array{Foo,1}:
    Foo([1])   
 #undef        
    Foo([3, 4])

Now I want to build an Bool array b that says whether each element of bar corresponds to an empty or unassigned vector. I try to write

julia> b = [isempty(f.v) for f in bar]
ERROR: UndefRefError: access to undefined reference
...

This also fails

julia> b = [!isassigned(bar, i) || isempty(f.v) for (i,f) in enumerate(bar)]
ERROR: UndefRefError: access to undefined reference

Same problem in other contexts such as all(isempty(f.v) for f in bar) for example.

Is there an elegant way to handle #undefs in this kind of iterations without writing out an explicit loop?

[EDIT: This works, but I still wonder if there is a cleaner way

b = [!isassigned(bar, i) || isempty(bar[i].v) for i in eachindex(bar)]

Maybe this is good enough… Sorry for the noise]

Yeah, the issue here is [... for f in bar], which implicitly does bar[i], which will error on #undef. Your eachindex(bar) solution is probably the best.

1 Like