From b90b45b01bba1f3fc241a96abd4ae5c8c314bb92 Mon Sep 17 00:00:00 2001 From: pqflx3 Date: Tue, 9 Oct 2018 11:25:25 +0000 Subject: 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 --- lib/pure/algorithm.nim | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 81badfae6..aea005ff1 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -227,7 +227,7 @@ proc merge[T](a, b: var openArray[T], lo, m, hi: int, else: 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.}, order = SortOrder.Ascending) = ## 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). ## The current implementation uses an iterative ## mergesort to achieve this. It uses a temporary sequence of - ## length ``a.len div 2``. Currently Nim does not support a - ## sensible default argument for ``cmp``, so you have to provide one - ## of your own. However, the ``system.cmp`` procs can be used: + ## length ``a.len div 2``. If you do not wish to provide your own + ## ``cmp``, you may use ``system.cmp`` or instead call the overloaded + ## version of ``sort``, which uses ``system.cmp``. ## ## .. code-block:: nim ## @@ -267,14 +267,31 @@ proc sort*[T](a: var openArray[T], dec(m, 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] = - ## returns `a` sorted by `cmp` in the specified `order`. + ## Returns `a` sorted by `cmp` in the specified `order`. result = newSeq[T](a.len) for i in 0 .. a.high: result[i] = a[i] 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 = ## Convenience template around the ``sorted`` proc to reduce typing. ## @@ -308,7 +325,7 @@ template sortedByIt*(seq1, op: untyped): untyped = result = cmp(a, b)) result -proc isSorted*[T](a: openarray[T], +func isSorted*[T](a: openArray[T], cmp: proc(x, y: T): int {.closure.}, order = SortOrder.Ascending): bool = ## 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: 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]] = ## produces the Cartesian product of the array. Warning: complexity ## may explode. -- cgit 1.4.1-2-gfad0