Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

julia-lang Check element type of arbitrarily nested array

Tags:

julia

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?
like image 402
Phuoc Avatar asked Jan 25 '17 05:01

Phuoc


3 Answers

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*)
}
like image 129
tim Avatar answered Nov 11 '22 14:11

tim


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

like image 31
Colin T Bowers Avatar answered Nov 11 '22 14:11

Colin T Bowers


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
like image 44
Gnimuc Avatar answered Nov 11 '22 14:11

Gnimuc