0
0

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言語での複数キーによるソートのサンプル

0
Posted at

以下は、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番目優先の比較になっている。
実行禁止:仕様と異なるソートになり誤解を招く。


いろいろ検証です。ありがとうございます。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?