diff --git a/src/Nulls.jl b/src/Nulls.jl index c40de64..d49cb32 100644 --- a/src/Nulls.jl +++ b/src/Nulls.jl @@ -121,6 +121,8 @@ xor(::Integer, ::Null) = null Return an iterator wrapping iterable `itr` which replaces [`null`](@ref) values with `replacement`. When applicable, the size of `itr` is preserved. +If the type of `replacement` differs from the element type of `itr`, +returned values are promoted to a common type. See also: [`Nulls.skip`](@ref), [`Nulls.fail`](@ref) @@ -132,6 +134,12 @@ julia> collect(Nulls.replace([1, null, 2], 0)) 0 2 + julia> collect(Nulls.replace([1, null, 2], 0.0)) + 3-element Array{Float64,1}: + 1.0 + 0.0 + 2.0 + julia> collect(Nulls.replace([1 null; 2 null], 0)) 2×2 Array{Int64,2}: 1 0 @@ -139,7 +147,10 @@ julia> collect(Nulls.replace([1 null; 2 null], 0)) ``` """ -replace(itr, replacement) = EachReplaceNull(itr, replacement) +function replace(itr, replacement) + U = promote_type(eltype(itr), typeof(replacement)) + EachReplaceNull(itr, convert(U, replacement)) +end struct EachReplaceNull{T, U} x::T replacement::U @@ -152,11 +163,12 @@ Base.length(itr::EachReplaceNull) = length(itr.x) Base.size(itr::EachReplaceNull) = size(itr.x) Base.start(itr::EachReplaceNull) = start(itr.x) Base.done(itr::EachReplaceNull, state) = done(itr.x, state) -Base.eltype(itr::EachReplaceNull) = - Union{Nulls.T(eltype(itr.x)), typeof(itr.replacement)} +Base.eltype(itr::EachReplaceNull{T, U}) where {T, U} = + promote_type(Nulls.T(eltype(itr.x)), U) @inline function Base.next(itr::EachReplaceNull, state) v, s = next(itr.x, state) - ((isnull(v) ? itr.replacement : v)::eltype(itr), s) + el = convert(eltype(itr), isnull(v) ? itr.replacement : v) + (el::eltype(itr), s) end """ diff --git a/test/runtests.jl b/test/runtests.jl index 0e0aa36..dd8a8db 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -129,6 +129,12 @@ using Base.Test, Nulls @test size(x) == (4,) @test collect(x) == collect(1:4) @test collect(x) isa Vector{Int} + x = Nulls.replace([1, 2, null, 4], 3.0) + @test eltype(x) === Float64 + @test length(x) == 4 + @test size(x) == (4,) + @test collect(x) == collect(1:4) + @test collect(x) isa Vector{Float64} x = Nulls.replace([1 2; null 4], 3) @test eltype(x) === Int @test length(x) == 4