I have Array{Tuple{A, B}}
and I want to unzip / move it to Tuple{Array{A}, Array{B}}
.
typealias MyIndexType Tuple{Bool, Int}
function test(x::MyIndexType)
# prepare for test data set.
myArray = Array{Tuple{MyIndexType, Float64}}(0)
push!(myArray, (x,1))
push!(myArray, (x,1))
push!(myArray, (x,1))
# transform
a, b = (zip(myArray...)...)
[a...]
end
test((true, 1))
>>>
3-element Array{Tuple{Bool,Int64},1}:
(true,1)
(true,1)
(true,1)
However, using @code_warntype
, the JIT can not infer the type a
, b
ahead of time.
Variables:
x::Tuple{Bool,Int64}
myArray::Array{Tuple{Tuple{Bool,Int64},Float64},1}
a::ANY
b::ANY
Body:
begin
myArray = (top(ccall))(:jl_alloc_array_1d,(top(apply_type))(Base.Array,Tuple{Tuple{Bool,Int64},Float64},1)::Type{Array{Tuple{Tuple{Bool,Int64},Float64},1}},(top(svec))(Base.Any,Base.Int)::SimpleVector,Array{Tuple{Tuple{Bool,Int64},Float64},1},0,0,0)::Array{Tuple{Tuple{Bool,Int64},Float64},1}
(Main.push!)(myArray::Array{Tuple{Tuple{Bool,Int64},Float64},1},(top(tuple))(x::Tuple{Bool,Int64},1)::Tuple{Tuple{Bool,Int64},Int64})::Array{Tuple{Tuple{Bool,Int64},Float64},1}
(Main.push!)(myArray::Array{Tuple{Tuple{Bool,Int64},Float64},1},(top(tuple))(x::Tuple{Bool,Int64},1)::Tuple{Tuple{Bool,Int64},Int64})::Array{Tuple{Tuple{Bool,Int64},Float64},1}
(Main.push!)(myArray::Array{Tuple{Tuple{Bool,Int64},Float64},1},(top(tuple))(x::Tuple{Bool,Int64},1)::Tuple{Tuple{Bool,Int64},Int64})::Array{Tuple{Tuple{Bool,Int64},Float64},1}
GenSym(0) = (top(_apply))((top(getfield))(Main,:call)::F,top(tuple),(top(_apply))((top(getfield))(Main,:call)::F,Main.zip,myArray::Array{Tuple{Tuple{Bool,Int64},Float64},1})::UNION{BASE.ZIP2{TUPLE{TUPLE{BOOL,INT64},FLOAT64},TUPLE{TUPLE{BOOL,INT64},FLOAT64}},TUPLE{TUPLE{BOOL,INT64},FLOAT64},ZIP{I,Z<:BASE.ABSTRACTZIPITERATOR}})::TUPLE
GenSym(4) = (Base.getfield)(GenSym(0),1)::ANY
GenSym(5) = (Base.box)(Base.Int,(Base.add_int)(1,1)::ANY)::Int64
a = GenSym(4)
GenSym(6) = (Base.getfield)(GenSym(0),2)::ANY
GenSym(7) = (Base.box)(Base.Int,(Base.add_int)(2,1)::ANY)::Int64
b = GenSym(6)
return (top(_apply))((top(getfield))(Main,:call)::F,top(vect),a)::ANY
end::ANY
Is there a way to make zip aware of result types?
Update
There are actually two problems.
He thinks he a
has a type a::TUPLE{UNION{FLOAT64,INT64},UNION{FLOAT64,INT64}}
, but he really has a typea::TUPLE{FLOAT64,FLOAT64}
function test{T}(x::T)
A = Tuple{T, Int}[]
for i in 1:3
push!(A, (x, 1))
end
d = zip(A[1], A[2])
a, b = d
a
end
@code_warntype test(3.0)
Variables:
x::Float64
A::Array{Tuple{Float64,Int64},1}
d::Base.Zip2{Tuple{Float64,Int64},Tuple{Float64,Int64}}
a::TUPLE{UNION{FLOAT64,INT64},UNION{FLOAT64,INT64}}
b::TUPLE{UNION{FLOAT64,INT64},UNION{FLOAT64,INT64}}
i::Int64
For zip
taking more than two arguments, note d has a nested type zip2
, which, I feel, can carry the strain of type input.
function test{T}(x::T)
A = Tuple{T, Int}[]
for i in 1:3
push!(A, (x, 1))
end
d = zip(A[1], A[2], A[3])
a, b = d
a
end
@code_warntype test(3.0)
Variables:
x::Float64
A::Array{Tuple{Float64,Int64},1}
d::Zip{Tuple{Float64,Int64},Base.Zip2{Tuple{Float64,Int64},Tuple{Float64,Int64}}}
a::TUPLE{UNION{FLOAT64,INT64},UNION{FLOAT64,INT64},UNION{FLOAT64,INT64}}
b::TUPLE{UNION{FLOAT64,INT64},UNION{FLOAT64,INT64},UNION{FLOAT64,INT64}}
i::Int64
Why am I interested in type?
It takes 10 + seconds to compile a, b = zip (A ...) of the following example, and the speed seems to be related to the length of A. (Julia 0.4)
const A = Tuple{Int, Int}[]
for i = 1:200
push!(A, (1, 1))
end
a, b = zip(A...)
a
https://github.com/JuliaLang/julia/issues/13722