如何将键值 table 转换为列表 lua
How to transform a key, value table into a list lua
在 lua 中有一个 table,例如:
tab = {a="hello", b="world"}
如何将其展平为键值列表:
{"a", "hello", "b", "world"}
我设法编写了一些似乎有效的代码:
function expand(t)
local i = 1
local res = {}
for k, v in pairs(t) do
res[i] = k
i = i + 1
res[i] = v
i = i + 1
end
return res
end
我想知道 lua 中是否有更紧凑的方法:
我唯一能想到的就是去掉不必要的i
.
function expand(t)
local res = {}
for k, v in pairs(t) do
res[#res + 1] = k
res[#res + 1] = v
end
return res
end
除此之外,我不知道任何其他可能的优化(在紧凑的意义上)。
我写了一个简单的测试,发现这段代码相对于 OP 代码的时间惩罚随着 table 的键数增加而增加。出于某种原因,它在 luajit 中比在 lua5.3 中增长得更快。
local function benchmark(funcs, t, times)
times = times or 1000000
local s, e
local diffs = {}
for name, f in pairs(funcs) do
s = os.clock()
for i = 1, times do
f(t)
end
e = os.clock()
diffs[name] = e - s
end
return diffs
end
-- base, length and insert are functions correspond to the OP's version,
-- the version in this answer and the version with table.insert respectively.
local funcs = { base = base, length = length, insert = insert }
io.write('nkeys\tbase\tlength\tinsert\n')
for _, nkeys in ipairs{4, 8, 16, 32, 64} do
-- get_tab(n) returns a table with n keys. Its definition is omitted.
local res = benchmark(funcs, get_tab(nkeys))
io.write(string.format("%d\t1.0\t%.2f\t%.2f\n",
nkeys, res.length/res.base, res.insert/res.base))
end
输出:
$ luajit ./flatten.lua
nkeys base length insert
4 1.0 1.15 1.55
8 1.0 1.33 1.89
16 1.0 1.55 2.47
32 1.0 1.72 2.82
64 1.0 2.00 3.72
$ lua5.3 ./flatten.lua
nkeys base length insert
4 1.0 1.13 1.56
8 1.0 1.24 1.78
16 1.0 1.28 1.95
32 1.0 1.36 2.12
64 1.0 1.56 2.34
我们还可以看到 table.insert()
比 res[#res + 1] =
还要慢。
在 lua 中有一个 table,例如:
tab = {a="hello", b="world"}
如何将其展平为键值列表:
{"a", "hello", "b", "world"}
我设法编写了一些似乎有效的代码:
function expand(t)
local i = 1
local res = {}
for k, v in pairs(t) do
res[i] = k
i = i + 1
res[i] = v
i = i + 1
end
return res
end
我想知道 lua 中是否有更紧凑的方法:
我唯一能想到的就是去掉不必要的i
.
function expand(t)
local res = {}
for k, v in pairs(t) do
res[#res + 1] = k
res[#res + 1] = v
end
return res
end
除此之外,我不知道任何其他可能的优化(在紧凑的意义上)。
我写了一个简单的测试,发现这段代码相对于 OP 代码的时间惩罚随着 table 的键数增加而增加。出于某种原因,它在 luajit 中比在 lua5.3 中增长得更快。
local function benchmark(funcs, t, times)
times = times or 1000000
local s, e
local diffs = {}
for name, f in pairs(funcs) do
s = os.clock()
for i = 1, times do
f(t)
end
e = os.clock()
diffs[name] = e - s
end
return diffs
end
-- base, length and insert are functions correspond to the OP's version,
-- the version in this answer and the version with table.insert respectively.
local funcs = { base = base, length = length, insert = insert }
io.write('nkeys\tbase\tlength\tinsert\n')
for _, nkeys in ipairs{4, 8, 16, 32, 64} do
-- get_tab(n) returns a table with n keys. Its definition is omitted.
local res = benchmark(funcs, get_tab(nkeys))
io.write(string.format("%d\t1.0\t%.2f\t%.2f\n",
nkeys, res.length/res.base, res.insert/res.base))
end
输出:
$ luajit ./flatten.lua
nkeys base length insert
4 1.0 1.15 1.55
8 1.0 1.33 1.89
16 1.0 1.55 2.47
32 1.0 1.72 2.82
64 1.0 2.00 3.72
$ lua5.3 ./flatten.lua
nkeys base length insert
4 1.0 1.13 1.56
8 1.0 1.24 1.78
16 1.0 1.28 1.95
32 1.0 1.36 2.12
64 1.0 1.56 2.34
我们还可以看到 table.insert()
比 res[#res + 1] =
还要慢。