I have this code in Ruby:
s = """
a
1
bb
2
33
33000
"""
a = s.split
h = Hash[*a]
puts h
# {"a"=>"1", "bb"=>"2", "33"=>"33000"}
How to achieve similar effect in Nim? I am looking for a flexible key accepting say these types: int, string and char.
Here is what I tried:
import tables
let s = """
1
xyz
2
a
3.1
b"""
let myTable = toTable(s). # Error: type mismatch...
Nim needs a fixed key type. While you could do a variant, this may be enough (using string as the flexible type):
import tables, strutils
let s = "a 1 bb 2 33 33000"
proc pair[T](x: openArray[T]): seq[(T,T)] =
for i in 0 ..< x.len div 2:
result.add (x[2*i], x[2*i+1])
echo toTable(s.split.pair)
produces:
{"33": "33000", "a": "1", "bb": "2"}
I don't know Ruby, but even there your numbers look like strings from "33" => "33000". Also, order is not preserved in Nim, though that may have been accidental in the Ruby. Also, my eg code does not but could check x.len mod 2 == 0 which a real impl should.Do you really need heterogeneously-keyed table? What's the use case? I very much doubt it you have one. If you really don't, here's my suggestion:
import tables, sugar, strutils
const text = "a\n1\nbb\n2\n33\n33000"
iterator chunkLines*(s: string): (string, string) =
## VERY dumb chunk iterator:
## - Doesn't check for empty lines
## - Doesn't check for odd number of lines
## - Copies a lot
var
i = true
x = (k:"", v:"")
for ss in s.split:
echo ss
if i:
x.k = ss
else:
x.v = ss
yield x
i = not i
let table = collect(initTable()):
for k, v in text.chunkLines(): {k: v}
echo($table)
Result: {"33": "33000", "bb": "2", "a": "1"}
aside: Mediocre iterator support in std strikes again: no proper partition, chunk, window generic iterators there.