From 02dbbddb2b7a132e80ad9e1aeb11f57e77a2ff2d Mon Sep 17 00:00:00 2001 From: Shashi Gowda Date: Wed, 20 Jun 2018 08:24:29 +0530 Subject: [PATCH] fix one-to-many map: fixes JuliaComputing/JuliaDB.jl#193 --- src/PooledArrays.jl | 24 ++++++++++++++++++++++-- test/runtests.jl | 4 ++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/PooledArrays.jl b/src/PooledArrays.jl index e41f15a..214b0ab 100644 --- a/src/PooledArrays.jl +++ b/src/PooledArrays.jl @@ -178,8 +178,28 @@ Base.find(pdv::PooledVector{Bool}) = find(convert(Vector{Bool}, pdv, false)) function Base.map{T,R<:Integer}(f, x::PooledArray{T,R}) ks = collect(keys(x.pool)) vs = collect(values(x.pool)) - newpool = Dict(zip(map(f, ks), vs)) - PooledArray(RefArray(x.refs), newpool) + ks1 = map(f, ks) + uks = Set(ks1) + if length(uks) < length(ks1) + # this means some keys have repeated + newpool = Dict{eltype(ks), eltype(vs)}() + translate = Dict{eltype(vs), eltype(vs)}() + i = 1 + for (k, k1) in zip(ks, ks1) + if haskey(newpool, k1) + translate[x.pool[k]] = newpool[k1] + else + newpool[k1] = i + translate[x.pool[k]] = i + i+=1 + end + end + refarray = map(x->translate[x], x.refs) + else + newpool = Dict(zip(map(f, ks), vs)) + refarray = copy(x.refs) + end + PooledArray(RefArray(refarray), newpool) end ############################################################################## diff --git a/test/runtests.jl b/test/runtests.jl index f03d271..5de5287 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -31,6 +31,10 @@ let a = rand(10), b = rand(10,10), c = rand(1:10, 1000) @test map(identity, pc) == pc @test map(x->2x, pc) == map(x->2x, c) + # case where the outputs are one-to-many + pa = PooledArray([1,2,3,4,5,6]) + @test map(isodd, pa) == [1,0,1,0,1,0] + px = PooledArray(rand(128)) py = PooledArray(rand(200))