Add algorithm.[sort,sorted,isSorted] overloads using 'system.cmp'. (#8778)
* Add algorithm.[sort,sorted,isSorted] overloads using 'system.cmp'. Fixes 8684. * Change signatures to 'func'. Improve overload sort doc comments
This commit is contained in:
parent
bc557e4c6a
commit
b90b45b01b
1 changed files with 31 additions and 7 deletions
|
|
@ -227,7 +227,7 @@ proc merge[T](a, b: var openArray[T], lo, m, hi: int,
|
||||||
else:
|
else:
|
||||||
if k < j: copyMem(addr(a[k]), addr(b[i]), sizeof(T)*(j-k))
|
if k < j: copyMem(addr(a[k]), addr(b[i]), sizeof(T)*(j-k))
|
||||||
|
|
||||||
proc sort*[T](a: var openArray[T],
|
func sort*[T](a: var openArray[T],
|
||||||
cmp: proc (x, y: T): int {.closure.},
|
cmp: proc (x, y: T): int {.closure.},
|
||||||
order = SortOrder.Ascending) =
|
order = SortOrder.Ascending) =
|
||||||
## Default Nim sort (an implementation of merge sort). The sorting
|
## Default Nim sort (an implementation of merge sort). The sorting
|
||||||
|
|
@ -235,9 +235,9 @@ proc sort*[T](a: var openArray[T],
|
||||||
## be O(n log n).
|
## be O(n log n).
|
||||||
## The current implementation uses an iterative
|
## The current implementation uses an iterative
|
||||||
## mergesort to achieve this. It uses a temporary sequence of
|
## mergesort to achieve this. It uses a temporary sequence of
|
||||||
## length ``a.len div 2``. Currently Nim does not support a
|
## length ``a.len div 2``. If you do not wish to provide your own
|
||||||
## sensible default argument for ``cmp``, so you have to provide one
|
## ``cmp``, you may use ``system.cmp`` or instead call the overloaded
|
||||||
## of your own. However, the ``system.cmp`` procs can be used:
|
## version of ``sort``, which uses ``system.cmp``.
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
##
|
##
|
||||||
|
|
@ -267,14 +267,31 @@ proc sort*[T](a: var openArray[T],
|
||||||
dec(m, s*2)
|
dec(m, s*2)
|
||||||
s = s*2
|
s = s*2
|
||||||
|
|
||||||
proc sorted*[T](a: openArray[T], cmp: proc(x, y: T): int {.closure.},
|
func sort*[T](a: var openArray[T], order = SortOrder.Ascending) =
|
||||||
|
## Sort an openarray in-place with a default lexicographical ordering.
|
||||||
|
runnableExamples:
|
||||||
|
var s = @[1,3,2,5,4]
|
||||||
|
s.sort
|
||||||
|
doAssert a == @[1,2,3,4,5]
|
||||||
|
sort(a, system.cmp, order)
|
||||||
|
|
||||||
|
func sorted*[T](a: openArray[T], cmp: proc(x, y: T): int {.closure.},
|
||||||
order = SortOrder.Ascending): seq[T] =
|
order = SortOrder.Ascending): seq[T] =
|
||||||
## returns `a` sorted by `cmp` in the specified `order`.
|
## Returns `a` sorted by `cmp` in the specified `order`.
|
||||||
result = newSeq[T](a.len)
|
result = newSeq[T](a.len)
|
||||||
for i in 0 .. a.high:
|
for i in 0 .. a.high:
|
||||||
result[i] = a[i]
|
result[i] = a[i]
|
||||||
sort(result, cmp, order)
|
sort(result, cmp, order)
|
||||||
|
|
||||||
|
func sorted*[T](a: openArray[T], order = SortOrder.Ascending): seq[T] =
|
||||||
|
## Returns `a` sorted with default lexicographical ordering
|
||||||
|
runnableExamples:
|
||||||
|
let orig = @[2,3,1,2]
|
||||||
|
let copy = orig.sorted()
|
||||||
|
doAssert orig == @[2,3,1,2]
|
||||||
|
doAssert copy == @[1,2,2,3]
|
||||||
|
return sorted(a, system.cmp, order)
|
||||||
|
|
||||||
template sortedByIt*(seq1, op: untyped): untyped =
|
template sortedByIt*(seq1, op: untyped): untyped =
|
||||||
## Convenience template around the ``sorted`` proc to reduce typing.
|
## Convenience template around the ``sorted`` proc to reduce typing.
|
||||||
##
|
##
|
||||||
|
|
@ -308,7 +325,7 @@ template sortedByIt*(seq1, op: untyped): untyped =
|
||||||
result = cmp(a, b))
|
result = cmp(a, b))
|
||||||
result
|
result
|
||||||
|
|
||||||
proc isSorted*[T](a: openarray[T],
|
func isSorted*[T](a: openArray[T],
|
||||||
cmp: proc(x, y: T): int {.closure.},
|
cmp: proc(x, y: T): int {.closure.},
|
||||||
order = SortOrder.Ascending): bool =
|
order = SortOrder.Ascending): bool =
|
||||||
## Checks to see whether `a` is already sorted in `order`
|
## Checks to see whether `a` is already sorted in `order`
|
||||||
|
|
@ -319,6 +336,13 @@ proc isSorted*[T](a: openarray[T],
|
||||||
if cmp(a[i],a[i+1]) * order > 0:
|
if cmp(a[i],a[i+1]) * order > 0:
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
func isSorted*[T](a: openArray[T], order = SortOrder.Ascending): bool =
|
||||||
|
## Checks whether `a` is sorted with a default lexicographical ordering
|
||||||
|
runnableExamples:
|
||||||
|
let test = @[1,1,2,3,5,8]
|
||||||
|
doAssert test.isSorted()
|
||||||
|
result = isSorted(a, system.cmp, order)
|
||||||
|
|
||||||
proc product*[T](x: openArray[seq[T]]): seq[seq[T]] =
|
proc product*[T](x: openArray[seq[T]]): seq[seq[T]] =
|
||||||
## produces the Cartesian product of the array. Warning: complexity
|
## produces the Cartesian product of the array. Warning: complexity
|
||||||
## may explode.
|
## may explode.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue