diff --git a/Project.toml b/Project.toml index 2310939..0606440 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "Missings" uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.0.2" +version = "1.1.0" [deps] DataAPI = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" diff --git a/src/Missings.jl b/src/Missings.jl index 68896a0..08ed26c 100644 --- a/src/Missings.jl +++ b/src/Missings.jl @@ -2,7 +2,7 @@ module Missings export allowmissing, disallowmissing, ismissing, missing, missings, Missing, MissingException, levels, coalesce, passmissing, nonmissingtype, - skipmissings + skipmissings, emptymissing using Base: ismissing, missing, Missing, MissingException @@ -459,7 +459,7 @@ end Return a vector similar to the array wrapped by the given `SkipMissings` iterator but skipping all elements with a `missing` value in one of the iterators passed to `skipmissing` and elements for which `f` returns `false`. This method -only applies when all iterators passed to `skipmissings` are arrays. +only applies when all iterators passed to `skipmissings` are arrays. # Examples ``` @@ -488,4 +488,30 @@ function filter(f, itr::SkipMissingsofArrays) y end +""" + emptymissing(f) + +Return a function that takes at least one positional argument `x` and +returns `missing` if `x` is empty (`isempty(x)` returns `true`) +and otherwise returns `f(x, args...; kwargs...)`, where `args` are following +positional arguments passed to `f` and `kwargs` are its keyword arguments. + +# Examples +``` +julia> emptymissing(last)([]) +missing + +julia> emptymissing(last)([1, 2, 3]) +3 + +julia> emptymissing(first)([], 2) +missing + +julia> emptymissing(first)([1], 2) +1-element Vector{Int64}: +1 +``` +""" +emptymissing(f) = (x, args...; kwargs...) -> isempty(x) ? missing : f(x, args...; kwargs...) + end # module diff --git a/test/runtests.jl b/test/runtests.jl index 8f563e2..92e8a2c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -246,4 +246,15 @@ struct CubeRooter end @inferred Union{Missing, Int} reduce(+, mx) end end + +@testset "emptymissing" begin + @test emptymissing(last)([]) === missing + @test emptymissing(last)([1, 2, 3]) === 3 + @test emptymissing(sum)(skipmissing(missings(Int, 3))) === missing + @test emptymissing(sum)(skipmissing([1, 2, 3])) === 6 + fun(a, b; c) = (b, c) + @test emptymissing(fun)([], 1, c=2) === missing + @test emptymissing(fun)(3, 1, c=2) == (1, 2) +end + end