弹出数组中的第一个元素

时间:2011-02-05 23:25:33

标签: arrays lua lua-table

我在Lua中有一个数组x。我想将head = x[1]rest =设置为数组的其余部分,以便rest[1] = x[2]rest[2] = x[3]等。

我该怎么做?

(注意:我不在乎原始数组是否会发生变异。在Javascript中我会head = x.shift()x会包含剩余的元素。)

3 个答案:

答案 0 :(得分:17)

head = table.remove(x, 1)

“Pop”有点用词不当,因为它意味着一个廉价的操作,并且删除表的第一个元素需要重新定位其余内容 - 因此JavaScript和其他语言中的名称为“shift”。

答案 1 :(得分:6)

您想要table.remove

local t = {1,2,3,4}
local head = table.remove(t,1)
print( head )
--> 1
print( #t )
--> 3
print( t[1] )
--> 2

正如@daurnimator所指出的,这需要Lua运行时中数组的底层实现付出很多努力,转移所有表元素。如果您可以向后表示数组,调用数组head中的最后一项,那么对table.remove()的调用将是一个便宜的流行音乐:

local t = {4,3,2,1}
local head = table.remove(t)
print(head)
--> 1
print( #t )
--> 3
print( t[#t] )
--> 2

或者,您可以选择将元素序列表示为linked list。在这种情况下,从列表的头部弹出一个项目也是一个便宜的操作(但是除非你跟踪列表中的'尾部',否则将一个项目推到最后):

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

特别注意

local head,rest = numbers.val, numbers.rest

不会修改任何数据结构,只会在链中的特定链接上为您提供rest句柄。

答案 2 :(得分:0)

通常在Lua中,将元素x插入序列的动作...

例如:S = {a,b,c,d,e,f}至S = {a,b,c,x,d,e,f}

...非常耗时,因为d必须移至索引5,e移至索引6,等等。

还有其他形式为S的序列,其中S [a] = b, S [b] = c,S [c] = d,S [d] = e和S [e] = f?这样,您只需输入:

S [c] = x S [x] = d

动臂,在两次操作中,x在c之后和d之前。