0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Lua言語のtable.sort関数の中の比較関数について

0
Posted at

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
  • ab はテーブルの中の2つの値
  • もし ab より「小さい」と判断できるなら 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

ポイント

  • ab はテーブルの要素(ここでは配列の中のテーブル)
  • 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
  • ただし、必ず真偽値(truefalse)を返すようにすること

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}

このプログラムの目的は、

  1. data の中身(キーと値の組)を「配列」に変換する
  2. キー(文字列)を基準にしてソートする
  3. ソートした結果を順に表示する

という流れになっています。


処理の詳細

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つの要素(ここでは ab)を受け取り、true または false を返します。

比較関数の説明

  • abitems 配列の各要素、つまり {キー, 値} のテーブルです。
  • a[1]a のキー(例:"foo")
  • b[1]b のキー(例:"bar")
  • a[1] < b[1] で「キーの文字列を辞書順で比較」しています。

つまり、

  • 比較関数は「a のキーが b のキーよりも辞書順で前にあれば true を返す」
  • これにより table.sortitems 配列を「キーの文字列順」に並び替えます。

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 を返す場合、ab より前に置く」動作をします。
  • ここで 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つの引数 ab を受け取り、a[1]b[1] より小さいかどうかを調べる関数」です。

何を比較しているか?

  • ab は**テーブル(配列)**です。
  • a[1]a の1番目の要素、b[1]b の1番目の要素を指します。
  • つまり「ab の1番目の値(ここではキーの文字列)を比較」しています。

返り値の意味

  • a[1] < b[1]true なら、関数は true を返します。
  • false なら、false を返します。

この関数は何のために使う?

Luaの table.sort 関数は、並べ替えのルールとして「比較関数」を受け取れます。
比較関数は「ab の前に置くべきなら true を返す」ルールを持ちます。

つまり、

  • この関数は「a[1]b[1] より小さい(文字列なら辞書順に前)なら、a を前に置く」ことを意味します。

具体例

例えば、

a = {"apple", 10}
b = {"banana", 20}

この時、

a[1] < b[1]  --> "apple" < "banana" --> true

なので、ab の前に置かれます。


まとめ

  • この関数は「テーブルの1番目の要素を比較して、昇順(小さい順)に並べる」ための比較関数です。
  • 主に table.sort の第2引数として使い、配列の並べ替えルールを決めます。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?