Hatena::Grouphackathon

zrail (a.k.a. tobira17, h14i, ...) の Learning Log

2010-04-25

[]Lua の復習とかしてみる その 4 05:31 Lua の復習とかしてみる その 4 - zrail (a.k.a. tobira17, h14i, ...) の Learning Log を含むブックマーク はてなブックマーク - Lua の復習とかしてみる その 4 - zrail (a.k.a. tobira17, h14i, ...) の Learning Log

ようやく第 2 部に突入。

5.1

カード型データベース。

5.2

テーブルの配列。ハッシュの話ですね。

テーブルの要素へのアクセスの仕方。

player = { name = "abc" }
player2 = { name = "foo" }
player3 = { name = "bar" }
members = {}
members[1] = player
members[2] = player2
members[3] = player3
--  とすると
print(members[1].name)
print(player.name)
--  どちらも同じ物を参照するようになる
5.3

テーブルのフィールドを追加する話。

2 つ目のやり方を使えば予約語もフィールド名として使える。やらないほうが良さそうだけどね。

player = { name = "abc" }
player.age = 20
player.["shoot"] = 1

まぁ当然と言えば当然だけど、 Lua の場合でも連想配列よりも通常の配列のほうが処理効率が高いらしい。

プログラマは配列と連想配列を区別して考える必要はあまりないけれど、 Lua の内部処理はちゃんと区別されていますよって話。

5.4

2 次元配列。

C の宣言と同じような感じ。テーブルの中にテーブルを持たせるって感じで書くのかと思ったけど、割と普通だね。

配列の長さが自由に変えられるからやってしまいそうだけど、下みたいな書き方は出来ないみたい。

mtx = {}
mtx[1] = {}
mtx[1][3] = 1  --  ok
mtx[2][1] = 2  --  error mtx[2] が用意されてないからダメ
5.5

テーブルのデータ処理。関数にテーブルのフィールド名を渡す方法。

function testPrint(array, field)
  for i = 1, table.getn(array) do
    member = array[i]
    print(member[field])
  end
end

array = {
  { number = 1 },
  { number = 2 },
  { number = 3 }
}

testPrint(array, "number")

なんかあからさまにサンプルですって感じの微妙なコードだな。まぁいいか。

注意点。

変数を事前に宣言をする必要がないという便利さとのトレードオフで、スペルミスが素通りされる危険がある。

上の例みたいな単純なコードならすぐに気づくけど、いくつかの変数を扱う場合は結構やりがちなミスだよね。

5.6

コンストラクタの話とテーブルのメンバに関数が入れられるよって話。

さらっと書いたけど、これは結構重要だな。

多分この辺のことを指して「 Luaオブジェクト指向言語モドキとしても使える」って話があるんだろう。

5.7

ソート。 table.sort() という関数があり、これに数値の配列を渡すと昇順にソートしてくれる。

table.sort() には 2 つ目のパラメータとして比較関数を渡すことが出来る。これによって降順にソートできる。

まぁだいたい C とかと一緒だね。

んで、 Lua 特有の話で、テーブルを渡した場合、比較関数を使って比較するフィールドを指定してやる必要がある。

5.8

文字列のソート。

ASCII 順にソートされる。大文字小文字を区別したくない場合は string.upper() か string.lower() を使って比較する前に揃えてあげる。

5.9

データベースというかテーブル内の検索。

5.10

テーブルの走査。

汎用 for ループktkr!

test = { name = "foo", str = "bar", num = 1 }
for key, val in pairs(test) do
  out = string.format("%-10s%s", key, val)
  print(out)
end

while ループでも next() を使うことでほぼ同様のことが出来る。

test = { name = "foo", str = "bar", num = 1 }
key, val = next(test)
while(key) do
  out = string.format("%-10s%s", key, val)
  print(out)
  key, val = next(test, key)
end

特に理由がなければ for と pairs() の組合せを使うのが無難。

while と next() のほうは、 2 つの next() が離れてしまうので可読性が落ちるから、ってことらしい。確かにそうかも知れない。