Skip to content

Commit 56785e8

Browse files
committed
Add isgreater
Defines a descending total order where unorderable values and missing are last. This makes defining min, argmin, etc, simpler.
1 parent 5efd675 commit 56785e8

File tree

4 files changed

+33
-1
lines changed

4 files changed

+33
-1
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ New library functions
9494
* New function `insorted` for determining whether an element is in a sorted collection or not ([#37490]).
9595
* New function `Base.rest` for taking the rest of a collection, starting from a specific
9696
iteration state, in a generic way ([#37410]).
97+
* New function `isgreater(a, b)` defines a descending total order where unorderable values and missing are ordered smaller than any regular value.
9798

9899
New library features
99100
--------------------

base/exports.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ export
656656
isequal,
657657
ismutable,
658658
isless,
659+
isgreater,
659660
ifelse,
660661
objectid,
661662
sizeof,

base/operators.jl

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ is defined, it is expected to satisfy the following:
141141
`isless(x, y) && isless(y, z)` implies `isless(x, z)`.
142142
143143
Values that are normally unordered, such as `NaN`,
144-
are ordered in an arbitrary but consistent fashion.
144+
are ordered after regular values.
145145
[`missing`](@ref) values are ordered last.
146146
147147
This is the default comparison used by [`sort`](@ref).
@@ -168,6 +168,28 @@ isless(x::AbstractFloat, y::AbstractFloat) = (!isnan(x) & (isnan(y) | signless(x
168168
isless(x::Real, y::AbstractFloat) = (!isnan(x) & (isnan(y) | signless(x, y))) | (x < y)
169169
isless(x::AbstractFloat, y::Real ) = (!isnan(x) & (isnan(y) | signless(x, y))) | (x < y)
170170

171+
"""
172+
isgreater(x, y)
173+
174+
Test whether `x` is greater than `y`, according to a fixed total order.
175+
`isgreater` is defined in terms of `isless`, but is not the opposite of that function.
176+
177+
`isless` defines a fixed total order that ascends with unorderable values (such as `NaN`) and
178+
[`missing`](@ref) ordered last (biggest).
179+
`isgreater` defines a fixed total order that descends with unorderable values
180+
and `missing` ordered last (smallest).
181+
182+
Values that are normally unordered, such as `NaN`,
183+
are ordered after regular values.
184+
[`missing`](@ref) values are ordered last.
185+
186+
# Implementation
187+
Types should usually not implement this function. Instead, implement `isless`.
188+
"""
189+
isgreater(a, b) = _is_unorderable(a) || _is_unorderable(b) ? isless(a, b) : isless(b, a)
190+
_is_unorderable(x) = !isa(x == x, Bool) || x != x
191+
192+
171193

172194
function ==(T::Type, S::Type)
173195
@_pure_meta

test/operators.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ import Base.<
8383

8484
@test isless('a','b')
8585

86+
@testset "isgreater" begin
87+
@test !isgreater(missing, 1)
88+
@test isgreater(5, 1)
89+
@test !isgreater(1, 5)
90+
@test isgreater(1, missing)
91+
@test isgreater(1, NaN)
92+
end
93+
8694
@testset "vectorized comparisons between numbers" begin
8795
@test 1 .!= 2
8896
@test 1 .== 1

0 commit comments

Comments
 (0)