-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add unzip #33324
Add unzip #33324
Conversation
CI failures unrelated, correct? |
CI failures unrelated |
@StefanKarpinski can you assign someone to review this? |
It feels like a lot of stuff to implement """
unzip(itrs) -> Vector{<:Vector}
The `unzip` function takes an iterator of iterators and returns a vector of
vectors such that `zip(unzip(itrs)...) == map(itr->tuple(itr...), itrs)`.
# Examples
julia> unzip(enumerate("Hello"))
2-element Array{Array{T,1} where T,1}:
[1, 2, 3]
['a', 'b', 'c']
julia> unzip([[1, 'a'], [2.5, 'z'], [0, 'x']])
2-element Array{Array{T,1} where T,1}:
Real[1, 2.5, 0]
['a', 'z', 'x']
"""
function unzip(itrs)
outer = iterate(itrs)
outer === nothing && return []
vals, state = outer
vecs = Vector[[val] for val in vals]
local n
if Base.haslength(itrs)
n = length(itrs)
for vec in vecs
sizehint!(vec, n)
end
end
while true
outer = iterate(itrs, state)
outer === nothing && return vecs
vals, state = outer
for (j, val) = enumerate(vals)
vec = vecs[j]
if !(val isa eltype(vec))
T = Base.promote_typejoin(typeof(val), eltype(vec))
vec = vecs[j] = copyto!(similar(vec, T), vec)
@isdefined(n) && sizehint!(vec, n)
end
push!(vec, val)
end
end
end |
I guess the question is what one wants function unzip(itrs; uneven::Bool=false)
n = Base.haslength(itrs) ? length(itrs) : -1
vecs = Vector[]
for itr in itrs
for (j, x) in enumerate(itr)
if length(vecs) < j
v = [x]
push!(vecs, v)
n ≥ 0 && sizehint!(v, n)
else
v = vecs[j]
if !(x isa eltype(v))
T = Base.promote_typejoin(typeof(x), eltype(v))
v = vecs[j] = copyto!(similar(v, T), v)
n ≥ 0 && sizehint!(v, n)
end
push!(v, x)
end
end
uneven || length(first(vecs)) == length(last(vecs)) ||
throw(ArgumentError("unzip called with uneven iterators"))
end
return vecs
end Works the same on evenly sized arrays but here's an example with unevenly sized ones: julia> unzip([[1, 'a'], [2.5, 'z', "extra"], [0, 'x']], uneven=true)
3-element Array{Array{T,1} where T,1}:
Real[1, 2.5, 0]
['a', 'z', 'x']
["extra"] This just goes through each iterable thing and collects into the vector at the corresponding index. |
I finally switched to Ubuntu, and suddenly building and testing Base became much more manageable! I think this should be pretty close to good.
Closes #13942