如何在 Lua 中获取表的最新 x 条目?
Posted
技术标签:
【中文标题】如何在 Lua 中获取表的最新 x 条目?【英文标题】:How to get the latest x entries of a table in Lua? 【发布时间】:2022-01-15 20:34:24 【问题描述】:如果我有 (例如) 一个包含 300 个条目的表,我将如何仅获取最新的 x 个条目? 我正在考虑做下一个,但我想知道是否有更好/更优化的方法来做这件事。
local TestTable =
-- Populate table
for i = 1, 300, 1 do
print('Adding: ' .. i)
table.insert(TestTable , i)
end
-- Get latest x of table
function GetLatestFromTable(OriginalTable, Amount)
local TableLength = #OriginalTable
local Retval =
for i = 1, Amount, 1 do
if TableLength - i <= 0 then break end -- Dont allow to go under 0
table.insert(Retval, OriginalTable[TableLength - i])
print("Adding to Retval: " .. OriginalTable[TableLength - i] .. ' (Index: ' .. TableLength - i .. ')')
end
return Retval
end
print(#TestTable)
local LatestTable = GetLatestFromTable(TestTable, 10)
print(#LatestTable)
【问题讨论】:
您可以将内部 if 移动到循环中,例如for i = math.max(1, #OriginalTable - Amount + 1), #OriginalTable do
。如果您想完全避免复制,可以使用元表来模拟切片,但这似乎有点过头了。
好的,我去试试,谢谢!
试试LatestTable = table.unpack(TestTable,#TestTable-100+1)
。
请注意,lhfs 解决方案不适用于很长的表,table.unpack
有限制
哦,如果你只想迭代子数组,你可以制作一个自定义迭代器。
【参考方案1】:
正如@Luke100000 所提到的,一种方法是使用Lua
自定义迭代器。在Lua
中,迭代器是一个特殊的函数,当被调用时,它会返回下一个值。这是因为函数是Lua
中的一等公民,并且它们可以使用名为closure
的机制引用先前的范围。
要回答这个问题,可以开始在给定范围内实现通用迭代器。
function IterateRange (Table, Min, Max)
local ClosureIndex = Min - 1
local ClosureMax = math.min(Max, #Table)
local function Closure ()
if (ClosureIndex < ClosureMax) then
ClosureIndex = ClosureIndex + 1
return Table[ClosureIndex]
end
end
return Closure
end
IterateRange
是一个返回anonymous function
的函数。匿名函数不带任何参数。它只是更新定义在IterateRange
的本地范围内的ClosureIndex
索引并返回表值。
匿名函数做的第一件事是增加ClosureIndex
。因此,ClosureIndex
必须初始化为 Min - 1
。
这个函数可以正常工作:
TestTable =
for i = 1, 300, 1 do
print('Adding: ' .. i)
table.insert(TestTable , i)
end
for Value in IterateRange(TestTable, 290, 300) do
print(Value)
end
290
291
292
293
294
295
296
297
298
299
300
现在,重用这个通用迭代器来迭代给定表的最后 N 个条目是很简单的:
function IterateLastEntries (Table, Count)
local TableSize = #Table
local StartIndex = (TableSize - Count)
return IterateRange(Table, StartIndex, TableSize)
end
它也可以按预期工作:
TestTable =
for i = 1, 300, 1 do
print('Adding: ' .. i)
table.insert(TestTable , i)
end
for Value in IterateLastEntries(TestTable, 10) do
print(Value)
end
290
291
292
293
294
295
296
297
298
299
300
最后,用完全可复制和可粘贴的解决方案总结所有这些:
TestTable =
for i = 1, 300, 1 do
print('Adding: ' .. i)
table.insert(TestTable , i)
end
function IterateRange (Table, Min, Max)
local ClosureIndex = Min - 1
local ClosureMax = math.min(Max, #Table)
local function Closure ()
if (ClosureIndex < ClosureMax) then
ClosureIndex = ClosureIndex + 1
return Table[ClosureIndex]
end
end
return Closure
end
function IterateLastEntries (Table, Count)
local TableSize = #Table
local StartIndex = (TableSize - Count)
return IterateRange(Table, StartIndex, TableSize)
end
for Value in IterateLastEntries(TestTable, 10) do
print(Value)
end
这应该返回:
290
291
292
293
294
295
296
297
298
299
300
我会让 OP 更新代码,以便为 30
条目实现相同的结果。
【讨论】:
编辑:我修复了函数IterateRange
中的两个问题,我们想使用math.min
而不是math.max
。我们还需要比较ClosureIndex
而不是Max
。【参考方案2】:
对于序列中的键(值是字符串/数字),调用table.concat()
允许范围参数。
local tab = "One", "Two", "Three", "Four", "Five"
print(table.concat(tab, '\n', #tab - 1, #tab)) -- Last two entries
见:table.concat()
【讨论】:
以上是关于如何在 Lua 中获取表的最新 x 条目?的主要内容,如果未能解决你的问题,请参考以下文章