如果您想保持原始表不变,您可以创建一个自定义的“按值排序”迭代器,如下所示:
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
每次在myTableset中添加或删除元素时sorted = nil。这让迭代器知道它需要重建sorted表(并重新排序)。
每次更新value嵌套表之一中的属性时,设置resort = true. 这让迭代器知道它必须执行一个table.sort.
现在,当您使用迭代器时,它将尝试并重新使用缓存sorted表中先前排序的结果。
如果它找不到sorted表(例如,在第一次使用迭代器时,或者因为您设置sorted = nil强制重建),它将重建它。如果它认为它需要求助(例如,在第一次使用时,或者如果sorted表被重建,或者如果你设置resort = true了),那么它将使用sorted表。