1. table.sortについて
Luaのtable.sort関数について、高校生向けにわかりやすく説明します。実際にサンプルをonecompiler.comで、実行して検証してみると何かしら感じ取れると思います。一歩一歩です。ありがとうございます。
table.sortについて
1. 役割(目的)
table.sortは、配列の中の要素を並べ替える(ソートする)ための関数です。
例)数字の一覧を小さい順に並べる、文字列の一覧をアルファベット順に並べる、といったことができます。
2. 使い方
table.sort(テーブル [, 比較関数])
- テーブル:並べ替えたい配列(整数の連続したキーを持つテーブル)
- 比較関数(省略可):2つの要素を受け取り、どちらが「前」に来るべきかを決める関数
3. 比較関数の書き方
比較関数は以下の形で書きます。
function(a, b)
return a < b -- aがbより小さい(前に来るべき)ならtrueを返す
end
-
aとbはテーブルの中の2つの値 - もし
aがbより「小さい」と判断できるならtrueを返す - そうでなければ
falseを返す
この関数を使うことで、自分で並べ替えのルールを決められます。
4. 比較関数を省略した場合
- 省略すると、Luaは自動で
<演算子による昇順ソートを行います。 - 数字なら小さい順、文字列なら辞書順(アルファベット順)になります。
5. 例
local data = {5, 2, 9, 1, 7}
-- 昇順に並べ替え(比較関数省略)
table.sort(data)
for i, v in ipairs(data) do
print(v) -- 1 2 5 7 9 の順に出力される
end
local data = {"banana", "apple", "cherry"}
-- 辞書順に並べ替え(比較関数省略)
table.sort(data)
for i, v in ipairs(data) do
print(v) -- apple banana cherry の順に出力
end
6. 比較関数の例(降順に並べる)
local data = {5, 2, 9, 1, 7}
table.sort(data, function(a, b)
return a > b -- 大きい方が前に来る(降順)
end)
for i, v in ipairs(data) do
print(v) -- 9 7 5 2 1 の順に出力される
end
7. 注意点
-
配列の途中に
nilを入れると、table.sortは正しく動きません。
配列は整数の連続したインデックスで管理してください。
例:{10, 20, nil, 40}はNG。 -
比較関数の戻り値は必ず真偽値(true/false)でなければなりません。
8. 反例(間違った使い方)
local data = {"a", "b", "c"}
-- ❌ 間違った比較関数(返り値が真偽値でない)
table.sort(data, function(a, b)
return a + b -- 実行禁止:文字列同士に + はできずエラーになる
end)
エラーメッセージ例:
stdin:1: attempt to perform arithmetic on a string value
stack traceback:
[C]: in function 'sort'
stdin:1: in main chunk
[C]: ?
まとめ
| 項目 | 内容 |
|---|---|
| 関数名 | table.sort |
| 目的 | 配列の要素を並べ替える |
| 引数 | 配列(テーブル)、オプションで比較関数 |
| 比較関数の条件 |
function(a,b) return a < b end など |
| 比較関数省略時の挙動 | 昇順ソート(数値は小さい順、文字列は辞書順) |
| 注意点 | 配列に途中でnilを入れないこと |
2. 比較関数は、昇順と降順だけですか。テーブルであればkeyとなるindexを指定してa[2]<b[2]のようなことも行いますか。
比較関数は昇順・降順だけではありません
Luaのtable.sortで使う比較関数は、任意のルールで2つの要素の順序を決める関数です。
つまり、昇順・降順に限らず、テーブルの中の特定のフィールド(キー)の値を比較して並べ替えることもできます。
例:テーブルの2番目の要素をキーにして昇順ソートする
local data = {
{"apple", 5},
{"banana", 3},
{"cherry", 7}
}
table.sort(data, function(a, b)
return a[2] < b[2] -- 2番目の要素(数値)を比較して昇順に並べ替え
end)
for i, v in ipairs(data) do
print(v[1], v[2])
end
実行結果:
banana 3
apple 5
cherry 7
ポイント
-
aとbはテーブルの要素(ここでは配列の中のテーブル) -
a[2]はそのテーブルの2番目の要素 - 比較関数の中で自由にアクセスして条件を決められます
応用例:複数キーによるソート(例:まず2番目の値で昇順、同じなら1番目の文字列で昇順)
table.sort(data, function(a, b)
if a[2] == b[2] then
return a[1] < b[1]
else
return a[2] < b[2]
end
end)
まとめ
- 比較関数は昇順・降順だけでなく、任意のルールで自由に書ける
- テーブルの特定のフィールド(キーや添え字)を使った比較もOK
- ただし、必ず真偽値(
trueかfalse)を返すようにすること
3. data={"a","z","b","c","m","o","n"}の要素文字列を昇順にソートしてください。
はい、Luaではtable.sort関数を使って、配列(テーブル)を昇順にソートできます。
table.sortの第2引数に比較関数を渡すことも可能です。比較関数は2つの要素を受け取り、左の要素が右の要素より「小さい」と判断される場合にtrueを返します。
今回のように文字列を昇順にソートしたい場合は、比較関数として
function(a, b)
return a < b
end
を渡せば正しく動作します。
以下、例コードです。
local data = {"a", "z", "b", "c", "m", "o", "n"}
-- 昇順ソート(a < b が trueなら左に来る)
table.sort(data, function(a, b)
return a < b
end)
-- 結果表示
for i, v in ipairs(data) do
print(v)
end
実行結果(昇順に並びます):
a
b
c
m
n
o
z
解説
-
table.sortは配列部分(連続した整数キー)を昇順またはユーザー定義の順序で並べ替えます。 - 比較関数は「左の値が右の値より小さい場合にtrue」を返す必要があります。
- 文字列はLuaの
<演算子で辞書順に比較されます。
反例(間違った比較関数)
-- ❌ 比較関数が逆(降順になる)
table.sort(data, function(a, b)
return a > b -- 実行禁止:降順になるので昇順を期待するなら誤り
end)
理由:a > bは降順ソートになるため「昇順にソートしてください」という課題には適さない。
反例(比較関数を渡さない場合)
-- ❌ table.sortに比較関数を渡さず、意図しない順序になる場合がある
table.sort(data)
これはLua標準で昇順になりますが、課題で「関数を使って」と指定されている場合はNG。
4. サンプル例その1
local data = {foo=10, bar=20, baz=30}
-- 1. キーと値のペアを配列に変換
local items = {}
for k, v in pairs(data) do
table.insert(items, {k, v})
end
-- 2. キーでソート(キーは文字列なので辞書順)
table.sort(items, function(a, b)
return a[1] < b[1]
end)
-- 3. 結果表示
for _, pair in ipairs(items) do
print(pair[1], pair[2])
end
プログラムの全体の目的
Luaのテーブル data は連想配列のように、キー(文字列)と値(数値)のペアを持っています。
local data = {foo=10, bar=20, baz=30}
このプログラムの目的は、
-
dataの中身(キーと値の組)を「配列」に変換する - キー(文字列)を基準にしてソートする
- ソートした結果を順に表示する
という流れになっています。
処理の詳細
1. キーと値のペアを配列に変換
local items = {}
for k, v in pairs(data) do
table.insert(items, {k, v})
end
-
pairs(data)は、dataの中のキーと値を順不同で取り出します。 -
table.insert(items, {k, v})は、items配列の末尾に{k, v}という2要素の小テーブルを入れています。 - この結果、
itemsは次のような形になります(順不同):
{
{"foo", 10},
{"bar", 20},
{"baz", 30}
}
2. キーでソート
table.sort(items, function(a, b)
return a[1] < b[1]
end)
-
table.sortはLua組み込みの配列ソート関数です。 - 2番目の引数には「比較関数」を渡しています。
- 比較関数は2つの要素(ここでは
aとb)を受け取り、trueまたはfalseを返します。
比較関数の説明
-
aとbはitems配列の各要素、つまり{キー, 値}のテーブルです。 -
a[1]はaのキー(例:"foo") -
b[1]はbのキー(例:"bar") -
a[1] < b[1]で「キーの文字列を辞書順で比較」しています。
つまり、
- 比較関数は「
aのキーがbのキーよりも辞書順で前にあればtrueを返す」 - これにより
table.sortはitems配列を「キーの文字列順」に並び替えます。
3. 結果表示
for _, pair in ipairs(items) do
print(pair[1], pair[2])
end
-
ipairs(items)はitems配列の要素を順番に取り出します。 -
pair[1]はキー、pair[2]は値です。 -
printでソートされたキーと値を表示します。
まとめ
-
dataの連想配列を配列形式に変換し、 - キーの文字列を基準に並べ替え(辞書順ソート)、
- 並べ替えた結果をキーと値のペアで表示しています。
重要ポイント(比較関数)
function(a, b)
return a[1] < b[1]
end
-
table.sortは「第2引数の比較関数がtrueを返す場合、aをbより前に置く」動作をします。 - ここで
a[1]とb[1]はそれぞれキーの文字列なので、<演算子は文字列の辞書順比較をします。 - そのため、この比較関数は「キーの文字列がアルファベット順(辞書順)で小さい順に並べる」という意味になります。
5. サンプル例その2
-- 連想配列の例
local data = {cat = 3, dog = 5, apple = 2}
-- キーと値のペアを配列に変換
local items = {}
for k, v in pairs(data) do
table.insert(items, {k, v})
end
-- キー(文字列)でソート
table.sort(items, function(a, b)
return a[1] < b[1]
end)
-- ソート結果を表示
for _, pair in ipairs(items) do
print(pair[1], pair[2])
end
実行結果
apple 2
cat 3
dog 5
ポイント
-
itemsは{"cat", 3},{"dog", 5},{"apple", 2}のような配列です。 -
table.sortに渡した関数は、各要素の1番目の値(キーの文字列)を比較しています。 - これにより、「apple」→「cat」→「dog」の順に並び替えられました。
比較関数について
function(a, b)
return a[1] < b[1]
end
これは「2つの引数 a と b を受け取り、a[1] が b[1] より小さいかどうかを調べる関数」です。
何を比較しているか?
-
aとbは**テーブル(配列)**です。 -
a[1]はaの1番目の要素、b[1]はbの1番目の要素を指します。 - つまり「
aとbの1番目の値(ここではキーの文字列)を比較」しています。
返り値の意味
-
a[1] < b[1]がtrueなら、関数はtrueを返します。 -
falseなら、falseを返します。
この関数は何のために使う?
Luaの table.sort 関数は、並べ替えのルールとして「比較関数」を受け取れます。
比較関数は「a を b の前に置くべきなら true を返す」ルールを持ちます。
つまり、
- この関数は「
a[1]がb[1]より小さい(文字列なら辞書順に前)なら、aを前に置く」ことを意味します。
具体例
例えば、
a = {"apple", 10}
b = {"banana", 20}
この時、
a[1] < b[1] --> "apple" < "banana" --> true
なので、a は b の前に置かれます。
まとめ
- この関数は「テーブルの1番目の要素を比較して、昇順(小さい順)に並べる」ための比較関数です。
- 主に
table.sortの第2引数として使い、配列の並べ替えルールを決めます。