Skip to content

Commit be54a6c

Browse files
authored
Add documentation for Base.Order module (#36886)
* Add docstrings for Base.Order module * Add documentation section for Base.Order * Add reference to documentation on Base.Order in isless() docstring
1 parent 112f7a1 commit be54a6c

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

base/operators.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ This is the default comparison used by [`sort`](@ref).
150150
Non-numeric types with a total order should implement this function.
151151
Numeric types only need to implement it if they have special values such as `NaN`.
152152
Types with a partial order should implement [`<`](@ref).
153+
See the documentation on [Alternate orderings](@ref) for how to define alternate
154+
ordering methods that can be used in sorting and related functions.
153155
154156
# Examples
155157
```jldoctest

base/ordering.jl

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,26 @@ export # not exported by Base
1818
DirectOrdering,
1919
lt, ord, ordtype
2020

21+
"""
22+
Base.Order.Ordering
23+
24+
Abstract type which represents a total order on some set of elements.
25+
26+
Use [`Base.Order.lt`](@ref) to compare two elements according to the ordering.
27+
"""
2128
abstract type Ordering end
2229

2330
struct ForwardOrdering <: Ordering end
31+
32+
"""
33+
ReverseOrdering(fwd::Ordering=Forward)
34+
35+
A wrapper which reverses an ordering.
36+
37+
For a given `Ordering` `o`, the following holds for all `a`, `b`:
38+
39+
lt(ReverseOrdering(o), a, b) == lt(o, b, a)
40+
"""
2441
struct ReverseOrdering{Fwd<:Ordering} <: Ordering
2542
fwd::Fwd
2643
end
@@ -31,9 +48,26 @@ ReverseOrdering() = ReverseOrdering(ForwardOrdering())
3148

3249
const DirectOrdering = Union{ForwardOrdering,ReverseOrdering{ForwardOrdering}}
3350

51+
"""
52+
Base.Order.Forward
53+
54+
Default ordering according to [`isless`](@ref).
55+
"""
3456
const Forward = ForwardOrdering()
57+
58+
"""
59+
Base.Order.Reverse
60+
61+
Reverse ordering according to [`isless`](@ref).
62+
"""
3563
const Reverse = ReverseOrdering()
3664

65+
"""
66+
By(by, order::Ordering=Forward)
67+
68+
`Ordering` which applies `order` to elements after they have been transformed
69+
by the function `by`.
70+
"""
3771
struct By{T, O} <: Ordering
3872
by::T
3973
order::O
@@ -42,10 +76,23 @@ end
4276
# backwards compatibility with VERSION < v"1.5-"
4377
By(by) = By(by, Forward)
4478

79+
"""
80+
Lt(lt)
81+
82+
`Ordering` which calls `lt(a, b)` to compare elements. `lt` should
83+
obey the same rules as implementations of [`isless`](@ref).
84+
"""
4585
struct Lt{T} <: Ordering
4686
lt::T
4787
end
4888

89+
"""
90+
Perm(order::Ordering, data::AbstractVector)
91+
92+
`Ordering` on the indices of `data` where `i` is less than `j` if `data[i]` is
93+
less than `data[j]` according to `order`. In the case that `data[i]` and
94+
`data[j]` are equal, `i` and `j` are compared by numeric value.
95+
"""
4996
struct Perm{O<:Ordering,V<:AbstractVector} <: Ordering
5097
order::O
5198
data::V
@@ -54,6 +101,11 @@ end
54101
ReverseOrdering(by::By) = By(by.by, ReverseOrdering(by.order))
55102
ReverseOrdering(perm::Perm) = Perm(ReverseOrdering(perm.order), perm.data)
56103

104+
"""
105+
lt(o::Ordering, a, b)
106+
107+
Test whether `a` is less than `b` according to the ordering `o`.
108+
"""
57109
lt(o::ForwardOrdering, a, b) = isless(a,b)
58110
lt(o::ReverseOrdering, a, b) = lt(o.fwd,b,a)
59111
lt(o::By, a, b) = lt(o.order,o.by(a),o.by(b))
@@ -78,6 +130,22 @@ function _ord(lt, by, order::Ordering)
78130
end
79131
end
80132

133+
"""
134+
ord(lt, by, rev::Union{Bool, Nothing}, order::Ordering=Forward)
135+
136+
Construct an [`Ordering`](@ref) object from the same arguments used by
137+
[`sort!`](@ref).
138+
Elements are first transformed by the function `by` (which may be
139+
[`identity`](@ref)) and are then compared according to either the function `lt`
140+
or an existing ordering `order`. `lt` should be [`isless`](@ref) or a function
141+
which obeys similar rules. Finally, the resulting order is reversed if
142+
`rev=true`.
143+
144+
Passing an `lt` other than `isless` along with an `order` other than
145+
[`Base.Order.Forward`](@ref) or [`Base.Order.Reverse`](@ref) is not permitted,
146+
otherwise all options are independent and can be used together in all possible
147+
combinations.
148+
"""
81149
ord(lt, by, rev::Nothing, order::Ordering=Forward) = _ord(lt, by, order)
82150

83151
function ord(lt, by, rev::Bool, order::Ordering=Forward)

doc/src/base/sort.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,32 @@ defalg(v::AbstractArray{<:Number}) = QuickSort
188188
As for numeric arrays, choosing a non-stable default algorithm for array types for which the notion
189189
of a stable sort is meaningless (i.e. when two values comparing equal can not be distinguished)
190190
may make sense.
191+
192+
## Alternate orderings
193+
194+
By default, `sort` and related functions use [`isless`](@ref) to compare two
195+
elements in order to determine which should come first. The
196+
[`Base.Order.Ordering`](@ref) abstract type provides a mechanism for defining
197+
alternate orderings on the same set of elements. Instances of `Ordering` define
198+
a [total order](https://en.wikipedia.org/wiki/Total_order) on a set of elements,
199+
so that for any elements `a`, `b`, `c` the following hold:
200+
201+
* Exactly one of the following is true: `a` is less than `b`, `b` is less than
202+
`a`, or `a` and `b` are equal (according to [`isequal`](@ref)).
203+
* The relation is transitive - if `a` is less than `b` and `b` is less than `c`
204+
then `a` is less than `c`.
205+
206+
The [`Base.Order.lt`](@ref) function works as a generalization of `isless` to
207+
test whether `a` is less than `b` according to a given order.
208+
209+
```@docs
210+
Base.Order.Ordering
211+
Base.Order.lt
212+
Base.Order.ord
213+
Base.Order.Forward
214+
Base.Order.ReverseOrdering
215+
Base.Order.Reverse
216+
Base.Order.By
217+
Base.Order.Lt
218+
Base.Order.Perm
219+
```

0 commit comments

Comments
 (0)