如果您想保持原始表不变,您可以创建一个自定义的“按值排序”迭代器,如下所示:
local function valueSort(a,b)
return a.value < b.value;
end
function sortByValue( tbl ) -- use as iterator
-- build new table to sort
local sorted = {};
for i,v in ipairs( tbl ) do sorted[i] = v end;
-- sort new table
table.sort( sorted, valueSort );
-- return iterator
return ipairs( sorted );
end
当sortByValue()
被调用时,它会克隆tbl
到一个新sorted
表,然后对已排序的表进行排序。然后它将sorted
表交给ipairs()
,并输出循环ipairs
使用的迭代器。for
要使用:
for i,v in sortByValue( myTable ) do
print(v)
end
虽然这可以确保您的原始表保持不变,但它的缺点是每次进行迭代时,迭代器都必须克隆myTable
以创建一个新sorted
表,然后table.sort
是该sorted
表。
sortByValue()
如果性能至关重要,您可以通过“缓存”迭代器完成的工作来大大加快速度。更新代码:
local resort, sorted = true;
local function valueSort(a,b)
return a.value < b.value;
end
function sortByValue( tbl ) -- use as iterator
if not sorted then -- rebuild sorted table
sorted = {};
for i,v in ipairs( tbl ) do sorted[i] = v end;
resort = true;
end
if resort then -- sort the 'sorted' table
table.sort( sorted, valueSort );
resort = false;
end
-- return iterator
return ipairs( sorted );
end
每次在myTable
set中添加或删除元素时sorted = nil
。这让迭代器知道它需要重建sorted
表(并重新排序)。
每次更新value
嵌套表之一中的属性时,设置resort = true
. 这让迭代器知道它必须执行一个table.sort
.
现在,当您使用迭代器时,它将尝试并重新使用缓存sorted
表中先前排序的结果。
如果它找不到sorted
表(例如,在第一次使用迭代器时,或者因为您设置sorted = nil
强制重建),它将重建它。如果它认为它需要求助(例如,在第一次使用时,或者如果sorted
表被重建,或者如果你设置resort = true
了),那么它将使用sorted
表。