Domanda

Ho un array x in lua. Vorrei impostare head = x[1] e rest = il resto dell'array, così che rest[1] = x[2], rest[2] = x[3], eccetera.

Come posso fare questo?

(Nota: non mi interessa se l'array originale viene mutata. In JavaScript lo farei head = x.shift() e x Conterrebbe gli elementi rimanenti.)

È stato utile?

Soluzione

head = table.remove(x, 1)

"Pop" è un po 'improprio, in quanto implica un'operazione economica e la rimozione del primo elemento di una tabella richiede il trasferimento del resto del contenuto-quindi il nome "Shift" in JavaScript e in alcune altre lingue.

Altri suggerimenti

Tu vuoi table.remove:

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

Come sottolinea @daurnimator, ciò richiede molto sforzo dall'implementazione sottostante degli array nel runtime di LUA, spostando tutti gli elementi del tavolo. Se puoi invece rappresentare i tuoi array all'indietro, chiamando l'ultimo elemento nell'array head, quindi la chiamata a table.remove() sarà un pop economico:

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

In alternativa, puoi scegliere di rappresentare la tua sequenza di elementi come a lista collegata. In questo caso, anche far scoppiare un articolo dalla testa dell'elenco è un'operazione economica (ma spingerne uno alla fine non lo è, a meno che non si tenga traccia della "coda" nella tua 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

Nota in particolare quello

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

non modifica alcuna struttura di dati ma ti dà solo un rest gestire un particolare collegamento nella catena.

Normalmente in Lua l'azione di inserire un elemento X in una sequenza ...

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

... richiede molto tempo perché D deve essere spostato nell'indice 5, e sull'indice 6 ecc.

Esiste qualche altra sequenza della forma S in cui S [A] = B, S [B] = C, S [C] = D, S [D] = E e S [E] = F? In questo modo, tutto ciò che devi fare è il tipo:

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

E boom, X è dopo C e prima di D in sole due operazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top