Skip to content

Commit 411df38

Browse files
committed
Improve sort!, searchsortedXXX and insorted doc
1 parent 4ff3842 commit 411df38

File tree

2 files changed

+87
-30
lines changed

2 files changed

+87
-30
lines changed

base/operators.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,6 @@ Types with a partial order should implement [`<`](@ref).
163163
See the documentation on [Alternate Orderings](@ref) for how to define alternate
164164
ordering methods that can be used in sorting and related functions.
165165
166-
See also [`isequal`](@ref), [`isunordered`](@ref).
167-
168166
# Examples
169167
```jldoctest
170168
julia> isless(1, 3)
@@ -330,6 +328,8 @@ New types with a canonical partial order should implement this function for
330328
two arguments of the new type.
331329
Types with a canonical total order should implement [`isless`](@ref) instead.
332330
331+
See also [`isunordered`](@ref).
332+
333333
# Examples
334334
```jldoctest
335335
julia> 'a' < 'b'

base/sort.jl

Lines changed: 85 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,9 @@ partialsort(v::AbstractVector, k::Union{Integer,OrdinalRange}; kws...) =
162162
# reference on sorted binary search:
163163
# http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary
164164

165-
# index of the first value of vector a that is greater than or equal to x;
166-
# returns lastindex(v)+1 if x is greater than all values in v.
165+
# Index of the first value of vector a that doesn't sort before x (for the
166+
# default order this means the first value less than or equivalent to x).
167+
# Returns lastindex(v)+1 if x sorts after all values of v.
167168
function searchsortedfirst(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::keytype(v) where T<:Integer
168169
hi = hi + T(1)
169170
len = hi - lo
@@ -181,8 +182,9 @@ function searchsortedfirst(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::key
181182
return lo
182183
end
183184

184-
# index of the last value of vector a that is less than or equal to x;
185-
# returns firstindex(v)-1 if x is less than all values of v.
185+
# Index of the last value of vector a that doesn't sort after x (for the
186+
# default order this means the last value less than or equaivalent to x).
187+
# returns firstindex(v)-1 if x sorts before all values of v.
186188
function searchsortedlast(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::keytype(v) where T<:Integer
187189
u = T(1)
188190
lo = lo - u
@@ -198,7 +200,7 @@ function searchsortedlast(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::keyt
198200
return lo
199201
end
200202

201-
# returns the range of indices of v equal to x
203+
# returns the range of indices of v equivalent to x
202204
# if v does not contain x, returns a 0-length range
203205
# indicating the insertion point of x
204206
function searchsorted(v::AbstractVector, x, ilo::T, ihi::T, o::Ordering)::UnitRange{keytype(v)} where T<:Integer
@@ -291,16 +293,24 @@ for s in [:searchsortedfirst, :searchsortedlast, :searchsorted]
291293
end
292294

293295
"""
294-
searchsorted(a, x; by=identity, lt=isless, rev=false)
296+
searchsorted(v, x; by=identity, lt=isless, rev=false)
295297
296-
Return the range of indices of `a` that compare as equal to `x` (using binary
297-
search), assuming that `a` is already sorted. Return an empty range located at
298-
the insertion point if `a` does not contain values equal to `x`.
298+
Return the range of indices in `v` where values are equivalent to `x`, or an
299+
empty range located at the insertion point if `v` does not contain values
300+
equivalent to `x` (see below for the definition of equivalence).
301+
302+
The range is found using binary search. The vector `v` must be sorted, or at
303+
least partitioned with respect to `x` such that all values that sort before `x`
304+
come first and all values that sort after `x` come last.
299305
300306
The `by`, `lt` and `rev` keywords modify what order is assumed for the data,
301307
as described in the [`sort!`](@ref) documentation.
302308
303-
See also: [`insorted`](@ref), [`searchsortedfirst`](@ref), [`sort!`](@ref), [`findall`](@ref).
309+
Values `x` and `y` are said equivalent if `lt(by(x), by(y))` and `lt(by(y),
310+
by(x))` both return `false`, and `x` is said to sort before `y` if `lt(by(x),
311+
by(y))` returns `true` (with `x` and `y` exchanged if `rev=true`).
312+
313+
See also: [`searchsortedfirst`](@ref), [`sort!`](@ref), [`insorted`](@ref), [`findall`](@ref).
304314
305315
# Examples
306316
```jldoctest
@@ -318,20 +328,30 @@ julia> searchsorted([1, 2, 4, 5, 5, 7], 9) # no match, insert at end
318328
319329
julia> searchsorted([1, 2, 4, 5, 5, 7], 0) # no match, insert at start
320330
1:0
331+
332+
julia> searchsorted([1, 0, 0, 2, 2, 7, 6], 2) # data unsorted but partitioned with respect to 2
333+
4:5
334+
335+
julia> searchsorted([1, -1, -2, 2, -2, 3, -4, 4], 2, by=abs) # sorted by absolute value, -2 equivalent to 2
336+
3:5
321337
```
322338
""" searchsorted
323339

324340
"""
325-
searchsortedfirst(a, x; by=identity, lt=isless, rev=false)
341+
searchsortedfirst(v, x; by=identity, lt=isless, rev=false)
326342
327-
Return the index of the first value in `a` greater than or equal to `x`,
328-
assuming that `a` is already sorted. Return `lastindex(a) + 1` if `x` is
329-
greater than all values in `a`.
343+
Return the index of the first value in `v` that doesn't sort before `x`.
344+
If all values in `v` sort before `x`, the function returns `lastindex(v) + 1`.
330345
331-
`insert!`ing `x` at this index will maintain sorted order.
346+
The index is found using binary search. The vector `v` must be sorted, or at
347+
least partitioned with respect to `x` such that all values that sort before `x`
348+
come first and all values that sort after `x` come last. `insert!`ing `x` at
349+
the returned index will maintain the sorted order (or partition).
332350
333351
The `by`, `lt` and `rev` keywords modify what order is assumed for the data,
334-
as described in the [`sort!`](@ref) documentation.
352+
as described in the [`sort!`](@ref) documentation. Value `x` is said to sort
353+
before `y` if `lt(by(x), by(y))` returns `true` (with `x` and `y` exchanged if
354+
`rev=true`).
335355
336356
See also: [`searchsortedlast`](@ref), [`searchsorted`](@ref), [`findfirst`](@ref).
337357
@@ -351,16 +371,29 @@ julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 9) # no match, insert at end
351371
352372
julia> searchsortedfirst([1, 2, 4, 5, 5, 7], 0) # no match, insert at start
353373
1
374+
375+
julia> searchsortedfirst([1, 0, 0, 2, 2, 7, 6], 2) # data unsorted but partitioned with respect to 2
376+
4
377+
378+
julia> searchsortedfirst([1, -1, -2, 2, -2, 3, -4, 4], 2, by=abs) # sorted by absolute value
379+
3
354380
```
355381
""" searchsortedfirst
356382

357383
"""
358-
searchsortedlast(a, x; by=identity, lt=isless, rev=false)
384+
searchsortedlast(v, x; by=identity, lt=isless, rev=false)
359385
360-
Return the index of the last value in `a` less than or equal to `x`, assuming
361-
that `a` is already sorted. Return `firstindex(a) - 1` if `x` is less than all
362-
values in `a`. The `by`, `lt` and `rev` keywords modify what order is assumed
363-
for the data, as described in the [`sort!`](@ref) documentation.
386+
Return the index of the last value in `v` that doesn't sort after `x`.
387+
If all values in `v` sort after `x`, the function returns `firstindex(v) - 1`.
388+
389+
The index is found using binary search. The vector `v` must be sorted, or at
390+
least partitioned with respect to `x` such that all values that sort before `x`
391+
come first and all values that sort after `x` come last.
392+
393+
The `by`, `lt` and `rev` keywords modify what order is assumed for the data,
394+
as described in the [`sort!`](@ref) documentation. Value `x` is said to sort
395+
before `y` if `lt(by(x), by(y))` returns `true` (with `x` and `y` exchanged if
396+
`rev=true`).
364397
365398
# Examples
366399
```jldoctest
@@ -378,16 +411,31 @@ julia> searchsortedlast([1, 2, 4, 5, 5, 7], 9) # no match, insert at end
378411
379412
julia> searchsortedlast([1, 2, 4, 5, 5, 7], 0) # no match, insert at start
380413
0
414+
415+
julia> searchsortedlast([1, 0, 0, 2, 2, 7, 6], 2) # data unsorted but partitioned with respect to 2
416+
5
417+
418+
julia> searchsortedlast([1, -1, -2, 2, -2, 3, -4, 4], 2, by=abs) # sorted by absolute value
419+
5
381420
```
382421
""" searchsortedlast
383422

384423
"""
385-
insorted(x, a; by=identity, lt=isless, rev=false) -> Bool
424+
insorted(x, v; by=identity, lt=isless, rev=false) -> Bool
386425
387-
Determine whether an item `x` is in the sorted collection `a`, in the sense that
388-
it is [`==`](@ref) to one of the values of the collection. The `by`, `lt` and
389-
`rev` keywords modify what order is assumed for the collection, as described in
390-
the [`sort!`](@ref) documentation.
426+
Determine whether a vector `v` contains any value equivalent to `x` (see below
427+
for the definition of equivalence).
428+
429+
The check is done using binary search. The vector `v` must be sorted, or at
430+
least partitioned with respect to `x` such that all values that sort before `x`
431+
come first and all values that sort after `x` come last.
432+
433+
The `by`, `lt` and `rev` keywords modify what order is assumed for the data,
434+
as described in the [`sort!`](@ref) documentation.
435+
436+
Values `x` and `y` are said equivalent if `lt(by(x), by(y))` and `lt(by(y),
437+
by(x))` both return `false`, and `x` is said to sort before `y` if `lt(by(x),
438+
by(y))` returns `true` (with `x` and `y` exchanged if `rev=true`).
391439
392440
See also [`in`](@ref).
393441
@@ -407,6 +455,12 @@ false
407455
408456
julia> insorted(0, [1, 2, 4, 5, 5, 7]) # no match
409457
false
458+
459+
julia> insorted(2, [1, 0, 2, 2, 7, 6]) # data unsorted but partitioned with respect to 2
460+
true
461+
462+
julia> insorted(2, [1, -1, -2, 3, -4, 4], by=abs) # sorted by absolute value
463+
true
410464
```
411465
412466
!!! compat "Julia 1.6"
@@ -1338,11 +1392,14 @@ for available algorithms). Elements are first transformed by the function `by`
13381392
and then compared according to either the function `lt` or the ordering
13391393
`order`. Finally, the resulting order is reversed if `rev=true`.
13401394
1341-
The `lt` function should define a strict partial order, that is, it should be
1395+
The `lt` function should define a strict weak ordering, that is, it should be
13421396
13431397
- irreflexive: `lt(x, x)` always yields `false`,
13441398
- asymmetric: if `lt(x, y)` yields `true` then `lt(y, x)` yields `false`,
1345-
- transitive: `lt(x, y) && lt(y, z)` implies `lt(x, z)`.
1399+
- transitive: `lt(x, y) && lt(y, z)` implies `lt(x, z)`,
1400+
- transitive in incomparability: `incomparable(x, y) && incomparable(y, z)`
1401+
implies `incomparable(x, z)`, where `incomparable(x, y)` is defined as
1402+
`!lt(x, y) && !lt(y, x)`.
13461403
13471404
For example `<` is a valid `lt` function but `≤` is not.
13481405

0 commit comments

Comments
 (0)