Skip to content

Implementing order functions where missings is the smallest value #144

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

Merged
merged 16 commits into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ This package provides additional functionality for working with `missing` values
- `Missings.replace` to wrap a collection in a (possibly indexable) iterator replacing `missing` with another value
- `Missings.fail` to wrap a collection in a (possibly indexable) iterator throwing an error if `missing` is encountered
- `skipmissings` to loop through a collection of iterators excluding indices where any iterators are `missing`
- `missingsmallest(f)` to create a partial order function that behaves as `f` and making `missing` the smallest value
- `missingsless` the standard `isless` function modified so that `missing` is less than any other element

## Contributing and Questions

Expand Down
30 changes: 29 additions & 1 deletion src/Missings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Missings

export allowmissing, disallowmissing, ismissing, missing, missings,
Missing, MissingException, levels, coalesce, passmissing, nonmissingtype,
skipmissings, emptymissing
skipmissings, emptymissing, missingsmallest, missingsless

using Base: ismissing, missing, Missing, MissingException

Expand Down Expand Up @@ -514,4 +514,32 @@ julia> emptymissing(first)([1], 2)
"""
emptymissing(f) = (x, args...; kwargs...) -> isempty(x) ? missing : f(x, args...; kwargs...)

# Variant of `isless` where `missing` is the smallest value
"""
missingsmallest(f::Function)

Creates a function of two arguments `x` and `y` that tests whether `x` is less
than `y` such that `missing` is always less than the other argument. In other
words, modifies the partial order function `f` such that `missing` is the
smallest possible value, and all other non-`missing` values are compared
according to `f`.

See also: [`missingsless`](@ref), the standard order where `missing` is the
smallest possible value.

# Examples
```
julia> missingsmallest(isless)(missing, Inf)
true

julia> missingsless(-Inf, missing)
false
```
"""
missingsmallest(f) = (x, y) -> ismissing(y) ? false : ismissing(x) ? true : f(x, y)

" The standard partial order `isless` modified so that `missing` is always the
smallest possible value."
const missingsless = missingsmallest(isless)

end # module
7 changes: 7 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,11 @@ struct CubeRooter end
@test emptymissing(fun)(3, 1, c=2) == (1, 2)
end

@testset "missingsmallest" begin
@test missingsless(missing, Inf) == true
@test missingsless(-Inf, missing) == false
@test missingsless(3, 4) == true
@test missingsless(-Inf, Inf) == true
end

end