元のテーブルを変更せずに残したい場合は、次のようなカスタムの「値による並べ替え」反復子を作成できます。
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
ます。