'sort' for ordered tables
This commit is contained in:
parent
1115c8bdf8
commit
b3e70febb4
2 changed files with 86 additions and 1 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2013 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -308,6 +308,52 @@ proc `$`*[A, B](t: TOrderedTable[A, B]): string =
|
||||||
## The `$` operator for ordered hash tables.
|
## The `$` operator for ordered hash tables.
|
||||||
dollarImpl()
|
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 -------------------------------
|
# ------------------------------ count tables -------------------------------
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,25 @@ const
|
||||||
"50": 344490, "60": 344491, "70": 344492,
|
"50": 344490, "60": 344491, "70": 344492,
|
||||||
"80": 344497}
|
"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:
|
block tableTest1:
|
||||||
var t = initTable[tuple[x, y: int], string]()
|
var t = initTable[tuple[x, y: int], string]()
|
||||||
t[(0,0)] = "00"
|
t[(0,0)] = "00"
|
||||||
|
|
@ -86,5 +105,25 @@ block countTableTest1:
|
||||||
block SyntaxTest:
|
block SyntaxTest:
|
||||||
var x = toTable[int, string]({:})
|
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"
|
echo "true"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue