Question

j'ai un tableau x en Lua.Je voudrais définir head = x[1] et rest = le reste du tableau, de sorte que rest[1] = x[2], rest[2] = x[3], etc.

Comment puis-je faire ceci?

(note:Je m'en fiche si le tableau d'origine est muté.En Javascript je ferais head = x.shift() et x contiendrait les éléments restants.)

Était-ce utile?

La solution

head = table.remove(x, 1)

"POP" est un peu inapproprié, car il implique une opération bon marché, et la suppression du premier élément d'une table nécessite de relocaliser le reste du contenu - d'où le nom "Shift" en JavaScript et d'autres langues.

Autres conseils

Tu veux table.remove:

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

Comme le souligne @Daurnimator, cela nécessite beaucoup d'efforts par la mise en œuvre sous-jacente des tableaux dans le runtime LUA, en déplacement de tous les éléments de la table. Si vous pouvez à la place représenter vos tableaux vers l'arrière, appelant le dernier élément du tableau head, alors l'appel à table.remove() sera une pop bon marché:

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

Alternativement, vous pouvez choisir de représenter votre séquence d'éléments comme un liste liée. Dans ce cas, faire éclater un élément de la tête de la liste est également une opération bon marché (mais en pousser un à la fin, à moins que vous ne gardiez une trace de la «queue» dans votre liste):

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

Noter en particulier que

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

ne modifie aucune structure de données mais vous donne simplement un rest gérer un lien particulier dans la chaîne.

Normalement en Lua l'action d'insérer un élément x dans une séquence...

Par exemple:S={a,b,c,d,e,f} à S={a,b,c,x,d,e,f}

... prend beaucoup de temps car d doit être déplacé vers l'index 5, e vers l'index 6, etc.

Y a-t-il une autre séquence de la forme s où s [a] = b, s [b] = c, s [c] = d, s [d] = e et s [e] = f?De cette façon, il vous suffit de taper :

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

et boum, x est après c et avant d en seulement deux opérations.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top