在 Lua 中从数组中弹出第一个元素

发布于 2024-10-16 02:04:43 字数 293 浏览 2 评论 0原文

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

我该怎么做?

(注意:我不关心原始数组是否发生变异。在 Javascript 中,我会执行 head = x.shift() ,并且 x 将包含剩余的元素。)

I have an array x in Lua. I would like to set head = x[1] and rest = the rest of the array, so that rest[1] = x[2], rest[2] = x[3], etc.

How can I do this?

(note: I don't care if the original array gets mutated. In Javascript I would do head = x.shift() and x would contain the remaining elements.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

围归者 2024-10-23 02:04:43

head = table.remove(x, 1)

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

head = table.remove(x, 1)

"Pop" is a bit of a misnomer, as it implies a cheap operation, and removing the first element of an table requires relocating the rest of the contents--hence the name "shift" in JavaScript and some other languages.

离笑几人歌 2024-10-23 02:04:43

您想要 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() 的调用将是一个廉价的 pop:

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

或者,您可以选择将元素序列表示为链接列表。在这种情况下,从列表头部弹出一个项目也是一种廉价的操作(但将一个项目推到末尾则不是,除非您跟踪列表中的“尾部”):

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句柄。

You want table.remove:

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

As @daurnimator points out, this requires a lot of effort by the underlying implementation of arrays in the Lua runtime, shifting all the table elements. If you can instead represent your arrays backwards, calling the last item in the array head, then the call to table.remove() will be a cheap pop:

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

Alternatively, you may choose to represent your sequence of elements as a linked list. In this case, popping an item off the head of the list is also a cheap operation (but pushing one onto the end is not, unless you keep track of the 'tail' in your 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

Note in particular that

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

does not modify any data structures but just gives you a rest handle on a particular link in the chain.

李白 2024-10-23 02:04:43

通常在 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 之前。

Normally in Lua the action of inserting an element x into a sequence...

Eg: S={a,b,c,d,e,f} to S={a,b,c,x,d,e,f}

...is very time-consuming because d has to be moved to index 5, e to index 6 etc.

Is there some other sequence of the form S where S[a]=b,
S[b]=c, S[c]=d, S[d]=e and S[e]=f? That way, all you have to do is type:

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

and boom, x is after c and before d in just two operations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文