mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 09:24:36 +00:00
'sort' for ordered tables
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2012 Andreas Rumpf
|
||||
# (c) Copyright 2013 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -308,6 +308,52 @@ proc `$`*[A, B](t: TOrderedTable[A, B]): string =
|
||||
## The `$` operator for ordered hash tables.
|
||||
dollarImpl()
|
||||
|
||||
proc sort*[A, B](t: var TOrderedTable[A, B],
|
||||
cmp: proc (x,y: tuple[key: A, val: B]): int) =
|
||||
## sorts `t` according to `cmp`. This modifies the internal list
|
||||
## that kept the insertion order, so insertion order is lost after this
|
||||
## call but key lookup and insertions remain possible after `sort` (in
|
||||
## contrast to the `sort` for count tables).
|
||||
var list = t.first
|
||||
var
|
||||
p, q, e, tail, oldhead: int
|
||||
nmerges, psize, qsize, i: int
|
||||
if t.counter == 0: return
|
||||
var insize = 1
|
||||
while true:
|
||||
p = list; oldhead = list
|
||||
list = -1; tail = -1; nmerges = 0
|
||||
while p >= 0:
|
||||
inc(nmerges)
|
||||
q = p
|
||||
psize = 0
|
||||
i = 0
|
||||
while i < insize:
|
||||
inc(psize)
|
||||
q = t.data[q].next
|
||||
if q < 0: break
|
||||
inc(i)
|
||||
qsize = insize
|
||||
while psize > 0 or (qsize > 0 and q >= 0):
|
||||
if psize == 0:
|
||||
e = q; q = t.data[q].next; dec(qsize)
|
||||
elif qsize == 0 or q < 0:
|
||||
e = p; p = t.data[p].next; dec(psize)
|
||||
elif cmp((t.data[p].key, t.data[p].val),
|
||||
(t.data[q].key, t.data[q].val)) <= 0:
|
||||
e = p; p = t.data[p].next; dec(psize)
|
||||
else:
|
||||
e = q; q = t.data[q].next; dec(qsize)
|
||||
if tail >= 0: t.data[tail].next = e
|
||||
else: list = e
|
||||
tail = e
|
||||
p = q
|
||||
t.data[tail].next = -1
|
||||
if nmerges <= 1: break
|
||||
insize = insize * 2
|
||||
t.first = list
|
||||
t.last = tail
|
||||
|
||||
# ------------------------------ count tables -------------------------------
|
||||
|
||||
type
|
||||
|
||||
@@ -19,6 +19,25 @@ const
|
||||
"50": 344490, "60": 344491, "70": 344492,
|
||||
"80": 344497}
|
||||
|
||||
sorteddata = {
|
||||
"---00": 346677844,
|
||||
"0": 34404,
|
||||
"1": 344004,
|
||||
"10": 34484,
|
||||
"11": 34474,
|
||||
"12": 789,
|
||||
"19": 34464,
|
||||
"2": 344774, "20": 34454,
|
||||
"3": 342244, "30": 34141244,
|
||||
"34": 123456,
|
||||
"4": 3412344, "40": 344114,
|
||||
"5": 341232144, "50": 344490,
|
||||
"6": 34214544, "60": 344491,
|
||||
"7": 3434544, "70": 344492,
|
||||
"8": 344544, "80": 344497,
|
||||
"9": 34435644,
|
||||
"90": 343}
|
||||
|
||||
block tableTest1:
|
||||
var t = initTable[tuple[x, y: int], string]()
|
||||
t[(0,0)] = "00"
|
||||
@@ -86,5 +105,25 @@ block countTableTest1:
|
||||
block SyntaxTest:
|
||||
var x = toTable[int, string]({:})
|
||||
|
||||
proc orderedTableSortTest() =
|
||||
var t = initOrderedTable[string, int](2)
|
||||
for key, val in items(data): t[key] = val
|
||||
for key, val in items(data): assert t[key] == val
|
||||
t.sort(proc (x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key))
|
||||
var i = 0
|
||||
# `pairs` needs to yield in sorted order:
|
||||
for key, val in pairs(t):
|
||||
doAssert key == sorteddata[i][0]
|
||||
doAssert val == sorteddata[i][1]
|
||||
inc(i)
|
||||
|
||||
# check that lookup still works:
|
||||
for key, val in pairs(t):
|
||||
doAssert val == t[key]
|
||||
# check that insert still works:
|
||||
t["newKeyHere"] = 80
|
||||
|
||||
|
||||
orderedTableSortTest()
|
||||
echo "true"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user