Jas*_*n S 8 arrays lua lua-table
我x在Lua 有一个数组.我想设置head = x[1]和rest =数组的休息,让rest[1] = x[2],rest[2] = x[3]等.
我怎样才能做到这一点?
(注意:我不在乎原始数组是否会发生变异.在Javascript中我会这样做,head = x.shift()并且x会包含剩余的元素.)
Mil*_*les 17
"Pop"有点用词不当,因为它意味着一个廉价的操作,并且删除表的第一个元素需要重新定位其余的内容 - 因此在JavaScript和其他一些语言中名称为"shift".
你想要table.remove:
local t = {1,2,3,4}
local head = table.remove(t,1)
print( head )
--> 1
print( #t )
--> 3
print( t[1] )
--> 2
Run Code Online (Sandbox Code Playgroud)
正如@daurnimator指出的那样,这需要Lua运行时中数组的底层实现付出很多努力,转移所有表元素.如果你可以向后代表你的数组,调用数组中的最后一项head,那么调用table.remove()将是一个便宜的pop:
local t = {4,3,2,1}
local head = table.remove(t)
print(head)
--> 1
print( #t )
--> 3
print( t[#t] )
--> 2
Run Code Online (Sandbox Code Playgroud)
或者,您可以选择将元素序列表示为链接列表.在这种情况下,从列表的头部弹出一个项目也是一个便宜的操作(但是除非你跟踪列表中的'tail',否则将一个项目推到最后):
local setm,getm = setmetatable,getmetatable
local linkedlist=setm({__index={
tail = function(l) while l.rest do l=l.rest end return l end, -- N.B. O(n)!
push = function(l,v,t) t=l:tail() t.rest=setm({val=v},getm(l)) return t end,
cram = function(l,v) return setm({val=v,rest=l},getm(l)) end,
each = function(l,v)
return function() if l then v,l=l.val,l.rest return v end end
end
}},{ __call=function(lmeta,v,...)
local head,tail=setm({val=v},lmeta) tail=head
for i,v in ipairs{...} do tail=tail:push(v) end
return head
end })
local numbers = linkedlist(1,2,3,4)
for n in numbers:each() do print(n) end
--> 1
--> 2
--> 3
--> 4
local head,rest = numbers.val, numbers.rest
print(head)
--> 1
for n in rest:each() do print(n) end
--> 2
--> 3
--> 4
local unrest = rest:cram('99')
for n in unrest:each() do print(n) end
--> 99
--> 2
--> 3
--> 4
Run Code Online (Sandbox Code Playgroud)
特别注意
local head,rest = numbers.val, numbers.rest
Run Code Online (Sandbox Code Playgroud)
不会修改任何数据结构,只是为您提供rest链中特定链接的句柄.