Pregunta

Tengo una matriz x en lua. Me gustaría establecer head = x[1] y rest = el resto de la matriz, de modo que rest[1] = x[2], rest[2] = x[3], etc.

¿Cómo puedo hacer esto?

(Nota: no me importa si la matriz original se muta. En JavaScript lo haría head = x.shift() y x contendría los elementos restantes).

¿Fue útil?

Solución

head = table.remove(x, 1)

"POP" es un nombre inapropiado, ya que implica una operación barata, y eliminar el primer elemento de una tabla requiere reubicar el resto del contenido, de ahí el nombre "cambio" en JavaScript y algunos otros idiomas.

Otros consejos

Usted quiere table.remove:

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

Como señala @daurnimator, esto requiere mucho esfuerzo por la implementación subyacente de matrices en el tiempo de ejecución de Lua, cambiando todos los elementos de la tabla. Si puede representar sus matrices hacia atrás, llamando al último elemento en la matriz head, entonces la llamada a table.remove() será un pop barato:

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

Alternativamente, puede optar por representar su secuencia de elementos como un lista enlazada. En este caso, aparecer un elemento del cabezal de la lista también es una operación barata (pero empujar uno al final no lo es, a menos que realice un seguimiento de la 'cola' en su lista):

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

Tenga en cuenta en particular que

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

no modifica ninguna estructura de datos, pero solo le da un rest manejar un enlace particular en la cadena.

Normalmente en lua la acción de insertar un elemento x en una secuencia ...

Eg: S = {A, B, C, D, E, F} a S = {A, B, C, X, D, E, F}

... lleva mucho tiempo porque D debe moverse al índice 5, E al índice 6, etc.

¿Hay alguna otra secuencia de la forma s donde s [a] = b, s [b] = c, s [c] = d, s [d] = e y s [e] = f? De esa manera, todo lo que tienes que hacer es escribir:

S [c] = x s [x] = D

y Boom, X está después de C y antes D en solo dos operaciones.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top