質問
配列があります x
ルアで。設定したいのですが head = x[1]
と rest =
残りの配列、それ rest[1] = x[2]
, rest[2] = x[3]
, 、など
これどうやってするの?
(注:元の配列が変異しているかどうかは気にしません。JavaScriptでは私がします head = x.shift()
と x
残りの要素が含まれます。)
解決
「ポップ」は安価な操作を意味するため、少し誤った名声です。テーブルの最初の要素を削除するには、コンテンツの残りの部分を再配置する必要があります。これは、JavaScriptと他の言語の「シフト」という名前です。
他のヒント
あなたが欲しい 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
または、一連の要素を次のように表現することを選択できます。 リンクリスト. 。この場合、リストのヘッドからアイテムをポップすることも安価な操作です(ただし、リストの「テール」を追跡しない限り、最後にプッシュすることはそうではありません):
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
チェーン内の特定のリンクを処理します。
通常、luaでは、要素xをシーケンスに挿入するアクション...
EG:s = {a、b、c、d、e、f}からs = {a、b、c、x、d、e、f}
... dをインデックス5に移動し、eインデックス6などに移動する必要があるため、非常に時間がかかります。
s [a] = b、s [b] = c、s [c] = d、s [d] = eおよびs [e] = f?そうすれば、あなたがしなければならないのはタイプだけです:
s [c] = x s [x] = d
boom、xはcの後、Dの前に2つの操作でdの前です。