Phuoc
Phuoc

Reputation: 1103

julia-lang Check element type of arbitrarily nested array

How could I check the element type of a nested array assumming I don't know the level of nesting?:

julia> a = [[[[1]]]]
1-element Array{Array{Array{Array{Int64,1},1},1},1}:
 Array{Array{Int64,1},1}[Array{Int64,1}[[1]]]

julia> etype(a)
 Int64?

Upvotes: 6

Views: 1653

Answers (3)

tim
tim

Reputation: 2096

As it is often the case for type computations, a recursive approach works very well:

nested_eltype(x) = nested_eltype(typeof(x))
nested_eltype{T<:AbstractArray}(::Type{T}) = nested_eltype(eltype(T))
nested_eltype{T}(::Type{T}) = T

This has no runtime overhead:

julia> @code_llvm nested_eltype([[[[[[[[[[1]]]]]]]]]])

define %jl_value_t* @julia_nested_eltype_71712(%jl_value_t*) #0 {
top:
  ret %jl_value_t* inttoptr (i64 140658266768816 to %jl_value_t*)
}

Upvotes: 11

Gnimuc
Gnimuc

Reputation: 8566

This is a generated version using .depth attribute:

@generated function etype{T}(x::T)
  ex = :(x)  
  for i = 1:T.depth
    ex = :($ex |> eltype)
  end
  ex
end

julia> a = [[[[1]]]]
1-element Array{Array{Array{Array{Int64,1},1},1},1}:
 Array{Array{Int64,1},1}[Array{Int64,1}[[1]]]

julia> etype(a)
Int64

Upvotes: 1

Colin T Bowers
Colin T Bowers

Reputation: 18560

There is probably a clever way to do this with one line, but in the meantime, you can use recursive calls to eltype to do this inside a while loop:

function nested_eltype(x::AbstractArray)
    y = eltype(x)
    while y <: AbstractArray
        y = eltype(y)
    end
    return(y)
end

Note that this works for nested arrays of any dimension, ie it doesn't just have to be Vector like the example in your question...

Upvotes: 3

Related Questions