以下は、Luaで複数キーによるソートを行うサンプルコードです。実際にサンプルをonecompiler.comで、実行して検証してみましょう。
サンプルその1
2番目の値(数値)で昇順にソートし、同じ値の場合は1番目の値(文字列)で昇順にソートします。
sort_sample.lua
-- 複数キーによるソートのサンプル
local data = {
{"banana", 3},
{"apple", 2},
{"orange", 3},
{"grape", 2},
{"cherry", 1}
}
-- ソート実行
table.sort(data, function(a, b)
if a[2] == b[2] then
return a[1] < b[1] -- 2番目の値が同じなら1番目の文字列で昇順
else
return a[2] < b[2] -- 2番目の値で昇順
end
end)
-- 結果表示
for i, v in ipairs(data) do
print(i, v[1], v[2])
end
-- 実行結果(期待値)
-- 1 cherry 1
-- 2 apple 2
-- 3 grape 2
-- 4 banana 3
-- 5 orange 3
【解説】
-
table.sortの第2引数に比較関数を渡します。 - 比較関数は
trueを返すとaがbの前に来ることを意味します。 - 2つのキーを使った条件分岐で、複数基準の昇順ソートを実現しています。
【反例】誤った複数キーソート例
-- ❌ 間違い例(a[1] < b[1]を先に比較してしまう)
table.sort(data, function(a, b)
if a[1] == b[1] then
return a[2] < b[2] -- 逆順で比較
else
return a[1] < b[1]
end
end)
【理由】
- 仕様と異なり、1番目の文字列で先に昇順ソートしてしまうため、
2番目の値による昇順ソートが優先されません。 - ソート結果が意図と異なり、期待値を得られません。
【実行禁止】
- 複数キーソートの優先順位が逆になるため、誤った結果になります。
【反例】Python風の文字列連結ミス(Luaでは誤り)
-- ❌ 間違い例(Python的書き方)
print("1位は" + data[1][1] + "です。")
【理由】
- Luaでは文字列連結は
..演算子を使います。 -
+演算子は数値計算用であり、文字列と使うとエラーになります。
【エラーメッセージ例】
stdin:1: attempt to perform arithmetic on a string value
stack traceback:
stdin:1: in main chunk
[C]: in ?
【実行禁止】
- 正しい文字列連結は
"1位は" .. data[1][1] .. "です。"としてください。
サンプルその2
以下のデータを用いて、複数キーによるソート(まず3番目の値で降順、同じなら2番目の値で降順)
- 第1キー:3番目の値(降順)
- 第2キー:2番目の値(降順)
sort_sample2.lua
local data = {
{"banana", 3, 300},
{"apple", 2, 150},
{"orange", 3, 500},
{"grape", 2, 100},
{"cherry", 1, 300},
{"mango", 4, 100}
}
table.sort(data, function(a, b)
if a[3] == b[3] then
return a[2] > b[2] -- 3番目が同じなら2番目で降順
else
return a[3] > b[3] -- 3番目の値で降順
end
end)
-- 結果表示
for _, v in ipairs(data) do
print(v[1], v[2], v[3])
end
【説明】
- table.sort の第2引数に比較関数を指定。
- 比較関数は a, b の2つの要素を受け取り、a が b より前に来るべきなら true を返す。
- a[3](3番目の値)を優先して降順に比較。
- 3番目の値が同じ場合は a[2](2番目の値)を降順で比較。
【実行結果】
orange 3 500
banana 3 300
cherry 1 300
apple 2 150
mango 4 100
grape 2 100
【反例】
-- ❌ 3番目の値で昇順(間違い)
table.sort(data, function(a, b)
if a[3] == b[3] then
return a[2] > b[2]
else
return a[3] < b[3] -- 昇順になってしまう(誤り)
end
end)
理由:指定は降順だが誤って昇順比較(<)にしているため、結果が逆になる。
実行禁止:目的に反するため誤用しない。
-- ❌ 複数キーの順番を逆にしている(間違い)
table.sort(data, function(a, b)
if a[2] == b[2] then
return a[3] > b[3] -- 2番目を優先すべきところを3番目優先にしていない
else
return a[2] > b[2]
end
end)
理由:3番目の値優先の指定に反し、2番目優先の比較になっている。
実行禁止:仕様と異なるソートになり誤解を招く。
いろいろ検証です。ありがとうございます。