ttables.nim 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. import tables, hashes
  2. import std/assertions
  3. type
  4. Person = object
  5. firstName, lastName: string
  6. proc hash(x: Person): Hash =
  7. ## Piggyback on the already available string hash proc.
  8. ##
  9. ## Without this proc nothing works!
  10. result = x.firstName.hash !& x.lastName.hash
  11. result = !$result
  12. var
  13. salaries = initTable[Person, int]()
  14. p1, p2: Person
  15. p1.firstName = "Jon"
  16. p1.lastName = "Ross"
  17. salaries[p1] = 30_000
  18. p2.firstName = "소진"
  19. p2.lastName = "박"
  20. salaries[p2] = 45_000
  21. var
  22. s2 = initOrderedTable[Person, int]()
  23. s3 = initCountTable[Person]()
  24. s2[p1] = 30_000
  25. s2[p2] = 45_000
  26. s3[p1] = 30_000
  27. s3[p2] = 45_000
  28. block: # Ordered table should preserve order after deletion
  29. var
  30. s4 = initOrderedTable[int, int]()
  31. s4[1] = 1
  32. s4[2] = 2
  33. s4[3] = 3
  34. var prev = 0
  35. for i in s4.values:
  36. doAssert(prev < i)
  37. prev = i
  38. s4.del(2)
  39. doAssert(2 notin s4)
  40. doAssert(s4.len == 2)
  41. prev = 0
  42. for i in s4.values:
  43. doAssert(prev < i)
  44. prev = i
  45. block: # Deletion from OrderedTable should account for collision groups. See issue #5057.
  46. # The bug is reproducible only with exact keys
  47. const key1 = "boy_jackpot.inGamma"
  48. const key2 = "boy_jackpot.outBlack"
  49. var t = {
  50. key1: 0,
  51. key2: 0
  52. }.toOrderedTable()
  53. t.del(key1)
  54. doAssert(t.len == 1)
  55. doAssert(key2 in t)
  56. var
  57. t1 = initCountTable[string]()
  58. t2 = initCountTable[string]()
  59. t1.inc("foo")
  60. t1.inc("bar", 2)
  61. t1.inc("baz", 3)
  62. t2.inc("foo", 4)
  63. t2.inc("bar")
  64. t2.inc("baz", 11)
  65. merge(t1, t2)
  66. doAssert(t1["foo"] == 5)
  67. doAssert(t1["bar"] == 3)
  68. doAssert(t1["baz"] == 14)
  69. let
  70. t1r = newCountTable[string]()
  71. t2r = newCountTable[string]()
  72. t1r.inc("foo")
  73. t1r.inc("bar", 2)
  74. t1r.inc("baz", 3)
  75. t2r.inc("foo", 4)
  76. t2r.inc("bar")
  77. t2r.inc("baz", 11)
  78. merge(t1r, t2r)
  79. doAssert(t1r["foo"] == 5)
  80. doAssert(t1r["bar"] == 3)
  81. doAssert(t1r["baz"] == 14)
  82. var
  83. t1l = initCountTable[string]()
  84. t2l = initCountTable[string]()
  85. t1l.inc("foo")
  86. t1l.inc("bar", 2)
  87. t1l.inc("baz", 3)
  88. t2l.inc("foo", 4)
  89. t2l.inc("bar")
  90. t2l.inc("baz", 11)
  91. block:
  92. const testKey = "TESTKEY"
  93. let t: CountTableRef[string] = newCountTable[string]()
  94. # Before, does not compile with error message:
  95. #test_counttable.nim(7, 43) template/generic instantiation from here
  96. #lib/pure/collections/tables.nim(117, 21) template/generic instantiation from here
  97. #lib/pure/collections/tableimpl.nim(32, 27) Error: undeclared field: 'hcode
  98. doAssert 0 == t[testKey]
  99. t.inc(testKey, 3)
  100. doAssert 3 == t[testKey]
  101. block:
  102. # Clear tests
  103. var clearTable = newTable[int, string]()
  104. clearTable[42] = "asd"
  105. clearTable[123123] = "piuyqwb "
  106. doAssert clearTable[42] == "asd"
  107. clearTable.clear()
  108. doAssert(not clearTable.hasKey(123123))
  109. doAssert clearTable.getOrDefault(42) == ""
  110. block: #5482
  111. var a = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
  112. var b = newOrderedTable[string, string](initialSize = 2)
  113. b["wrong?"] = "foo"
  114. b["wrong?"] = "foo2"
  115. doAssert a == b
  116. block: #5482
  117. var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
  118. var b = newOrderedTable[string, string](initialSize = 2)
  119. b["wrong?"] = "foo"
  120. b["wrong?"] = "foo2"
  121. doAssert a == b
  122. block: #5487
  123. var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
  124. var b = newOrderedTable[string, string]() # notice, default size!
  125. b["wrong?"] = "foo"
  126. b["wrong?"] = "foo2"
  127. doAssert a == b
  128. block: #5487
  129. var a = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
  130. var b = newOrderedTable[string, string]() # notice, default size!
  131. b["wrong?"] = "foo"
  132. b["wrong?"] = "foo2"
  133. doAssert a == b
  134. block:
  135. var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
  136. var b = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
  137. var c = newOrderedTable[string, string]() # notice, default size!
  138. c["wrong?"] = "foo"
  139. c["wrong?"] = "foo2"
  140. doAssert a == b
  141. doAssert a == c
  142. block: #6250
  143. let
  144. a = {3: 1}.toOrderedTable
  145. b = {3: 2}.toOrderedTable
  146. doAssert((a == b) == false)
  147. doAssert((b == a) == false)
  148. block: #6250
  149. let
  150. a = {3: 2}.toOrderedTable
  151. b = {3: 2}.toOrderedTable
  152. doAssert((a == b) == true)
  153. doAssert((b == a) == true)
  154. block: # CountTable.smallest
  155. let t = toCountTable([0, 0, 5, 5, 5])
  156. doAssert t.smallest == (0, 2)
  157. block: #10065
  158. let t = toCountTable("abracadabra")
  159. doAssert t['z'] == 0
  160. var t_mut = toCountTable("abracadabra")
  161. doAssert t_mut['z'] == 0
  162. # the previous read may not have modified the table.
  163. doAssert t_mut.hasKey('z') == false
  164. t_mut['z'] = 1
  165. doAssert t_mut['z'] == 1
  166. doAssert t_mut.hasKey('z') == true
  167. block: #12813 #13079
  168. var t = toCountTable("abracadabra")
  169. doAssert len(t) == 5
  170. t['a'] = 0 # remove a key
  171. doAssert len(t) == 4
  172. block:
  173. var tp: Table[string, string] = initTable[string, string]()
  174. doAssert "test1" == tp.getOrDefault("test1", "test1")
  175. tp["test2"] = "test2"
  176. doAssert "test2" == tp.getOrDefault("test2", "test1")
  177. var tr: TableRef[string, string] = newTable[string, string]()
  178. doAssert "test1" == tr.getOrDefault("test1", "test1")
  179. tr["test2"] = "test2"
  180. doAssert "test2" == tr.getOrDefault("test2", "test1")
  181. var op: OrderedTable[string, string] = initOrderedTable[string, string]()
  182. doAssert "test1" == op.getOrDefault("test1", "test1")
  183. op["test2"] = "test2"
  184. doAssert "test2" == op.getOrDefault("test2", "test1")
  185. var orf: OrderedTableRef[string, string] = newOrderedTable[string, string]()
  186. doAssert "test1" == orf.getOrDefault("test1", "test1")
  187. orf["test2"] = "test2"
  188. doAssert "test2" == orf.getOrDefault("test2", "test1")
  189. block tableWithoutInit:
  190. var
  191. a: Table[string, int]
  192. b: Table[string, int]
  193. c: Table[string, int]
  194. d: Table[string, int]
  195. e: Table[string, int]
  196. a["a"] = 7
  197. doAssert a.hasKey("a")
  198. doAssert a.len == 1
  199. doAssert a["a"] == 7
  200. a["a"] = 9
  201. doAssert a.len == 1
  202. doAssert a["a"] == 9
  203. doAssert b.hasKeyOrPut("b", 5) == false
  204. doAssert b.hasKey("b")
  205. doAssert b.hasKeyOrPut("b", 8)
  206. doAssert b["b"] == 5
  207. doAssert c.getOrDefault("a") == 0
  208. doAssert c.getOrDefault("a", 3) == 3
  209. c["a"] = 6
  210. doAssert c.getOrDefault("a", 3) == 6
  211. doAssert d.mgetOrPut("a", 3) == 3
  212. doAssert d.mgetOrPut("a", 6) == 3
  213. var x = 99
  214. doAssert e.pop("a", x) == false
  215. doAssert x == 99
  216. e["a"] = 77
  217. doAssert e.pop("a", x)
  218. doAssert x == 77
  219. block orderedTableWithoutInit:
  220. var
  221. a: OrderedTable[string, int]
  222. b: OrderedTable[string, int]
  223. c: OrderedTable[string, int]
  224. d: OrderedTable[string, int]
  225. a["a"] = 7
  226. doAssert a.hasKey("a")
  227. doAssert a.len == 1
  228. doAssert a["a"] == 7
  229. a["a"] = 9
  230. doAssert a.len == 1
  231. doAssert a["a"] == 9
  232. doAssert b.hasKeyOrPut("b", 5) == false
  233. doAssert b.hasKey("b")
  234. doAssert b.hasKeyOrPut("b", 8)
  235. doAssert b["b"] == 5
  236. doAssert c.getOrDefault("a") == 0
  237. doAssert c.getOrDefault("a", 3) == 3
  238. c["a"] = 6
  239. doAssert c.getOrDefault("a", 3) == 6
  240. doAssert d.mgetOrPut("a", 3) == 3
  241. doAssert d.mgetOrPut("a", 6) == 3
  242. block countTableWithoutInit:
  243. var
  244. a: CountTable[string]
  245. b: CountTable[string]
  246. c: CountTable[string]
  247. d: CountTable[string]
  248. e: CountTable[string]
  249. a["a"] = 7
  250. doAssert a.hasKey("a")
  251. doAssert a.len == 1
  252. doAssert a["a"] == 7
  253. a["a"] = 9
  254. doAssert a.len == 1
  255. doAssert a["a"] == 9
  256. doAssert b["b"] == 0
  257. b.inc("b")
  258. doAssert b["b"] == 1
  259. doAssert c.getOrDefault("a") == 0
  260. doAssert c.getOrDefault("a", 3) == 3
  261. c["a"] = 6
  262. doAssert c.getOrDefault("a", 3) == 6
  263. e["f"] = 3
  264. merge(d, e)
  265. doAssert d.hasKey("f")
  266. d.inc("f")
  267. merge(d, e)
  268. doAssert d["f"] == 7