LUA TABLE関数ライブラリ(一)――理論
9782 ワード
第19章Tableライブラリtableライブラリは、いくつかの操作tableの補助関数からなる.彼の主な役割の一つはLuaにおけるarrayの大きさに対して合理的な解釈を与えることである.またlistから削除要素を挿入する関数やarray要素をソートする関数もいくつか用意されています.19.1配列サイズLuaではarrayが最後の非nil要素で終わるとよく仮定している.この伝統的な約束には弊害がある:私たちのarrayにはnil要素を持つことができない.ほとんどのアプリケーションでは、この制限は問題ではありません.例えば、すべてのarrayに固定されたタイプがある場合です.しかし、arrayはnil要素を持つ必要がある場合があります.この場合、arrayの大きさを明確に示す方法が必要です.Tableライブラリは、2つの関数がarrayを操作するサイズを定義します.getnは、arrayのサイズを返します.setn、arrayのサイズを設定します.前述したように、この2つの方法はtableの1つの属性に関連しています.tableの1つのドメインにこの属性を保存するか、独立した(weak)tableを使用してtableとこの属性を関連付けます.2つの方法にはそれぞれメリットとデメリットがあるので、tableライブラリではこの2つの方法を使用しています.通常、tableを呼び出す.setn(t,n)は、tとnを内部(weak)tableに関連付けるtableを呼び出す.getn(t)は、内部tableとtに関連付けられた値を得る.しかしながら、テーブルtに数値nを有するドメインがある場合、setnはこの値を変更し、getnはこの値を返す.Getn関数には、上記の方法でarrayのサイズを返すことができない場合、最初のnil要素が見つかるまでarrayを巡回する元の方法があります.そのため、arrayでtableをずっと使用することができます.getn(t)は正しい結果を得た.例を見てみましょう.
デフォルトでは、setnとgetnは内部テーブルストレージテーブルのサイズを使用します.これはarrayを汚染する余分な元素を使用しないため、最もきれいな選択です.しかしながら、nドメインを使用する方法にもいくつかの利点がある.可変パラメータを持つ関数種では、Luaカーネルはこの方法を使用してarg配列のサイズを設定します.カーネルはライブラリに依存しないため、setnを使用できません.もう1つの利点は、arrayが作成されたときに、上記の例で見たように、彼のサイズを直接初期化できることです.setnとgetnを使用してarrayのサイズを操作するのは、ドメインnにサイズがあることを知っていても良い習慣です.tableライブラリのすべての関数(sort、concat、insertなど)はこの習慣に従います.実際には、setnを提供してドメインnの値を変更するのは、古いluaバージョンと互換性を持つためであり、この特性は将来のバージョンで変更される可能性があります.安全のため、この特性に依存すると仮定しないでください.getnを使用して配列サイズを取得し、setnを使用して配列サイズを設定してください.
19.2 tableライブラリの挿入/削除には、リストの任意の場所から要素を挿入および削除する関数があります.table.Insert関数はarray指定の位置に要素を挿入し、後ろの他のすべての要素を後ろに移動します.また、insertはarrayのサイズを変更します.例えば、aが配列{10,20,30}である場合、tableが呼び出される.Insert(a,1,15)後,aは{15,10,20,30}となる.よく使用される特殊な場合は、位置パラメータを持たずにinsertを呼び出すと、arrayの最後の位置に要素が挿入されます(したがって、要素の移動は必要ありません).次のコードは、プログラムに行ごとに独立し、すべての行をarrayに保存します.
table.remove関数は、配列内の指定された位置の要素を削除し、この要素を返します.その後の要素はすべて前に移動し、配列のサイズが変わります.位置パラメータ呼び出しがない場合、arrayの最後の要素を削除します.この2つの関数を使用すると、スタック、キュー、および両端キューが容易に実現されます.構造をa={}に初期化できます.1つのpush操作はtableに等しい.insert(a,x);1つのpop操作はtableに等しい.remove(a).構造の他端に要素を挿入するにはtableを使用します.insert(a,1,x);削除要素用table.remove(a,1).最後の2つの操作は、要素を往復移動しなければならないため、特に有効ではありません.しかしながら,tableライブラリのこれらの関数はC実装を用いるため,小さな配列(数百要素)にとって効率に問題はない.
19.3ソート
もう一つの役に立つ関数はtableです.sort.彼には2つのパラメータがあります.要素を格納するarrayとソート関数です.ソート関数には2つのパラメータがあり、arrayでソートした最初のパラメータが2番目のパラメータの前にある場合は、ソート関数はtrueを返さなければなりません.ソート関数が指定されていない場合、sortはデフォルトのオペレータより小さいオペレータを使用して比較します.
一般的なエラーは、テーブルの下付きフィールドをソートしようとすることです.1つのテーブルでは、すべての下付き文字が1つの集合を構成しますが、無秩序です.彼らをソートしたい場合は、arrayにコピーしてこのarrayをソートする必要があります.例を見て、上記のソースファイルを読み取り、ソースファイルの各関数が定義されている場所の行番号を示すテーブルを作成したと仮定します.
これらの関数名をアルファベット順で印刷したい場合は、pairsを使用してこのテーブルを巡回すると、関数名が表示される順序はランダムになります.しかし、これらの名前はテーブルのkeyであるため、直接ソートすることはできません.これらの関数名を配列内に配置すると、この配列をソートできます.まず、これらの関数名を保存する配列を作成し、ソートして結果を印刷する必要があります.
注意,Luaにとって配列も無秩序である.しかし、カウントする方法を知っているので、ソートされた下付きアクセス配列を使用すれば、ソートされた関数名を得ることができます.これがpairsではなくipairsを使用して配列を巡る理由です.前者はkeyの順序1,2,⋯⋯を用い,後者のテーブルの自然記憶順序である.より良い解決策があり、key値に基づいてこのテーブルを遍歴する反復子を書くことができます.オプションのパラメータfは、ソート方法を指定することができる.まず、ソートされたkeysを配列内に配置し、この配列を巡り、元のテーブルからkeyとvalueを返します.
この関数があれば、これらの関数名をアルファベット順に印刷しやすく、ループします.
印刷結果:
1 print(table.getn{10,2,4}) --> 3
2 print(table.getn{10,2,nil}) --> 2
3 print(table.getn{10,2,nil; n=3}) --> 3
4 print(table.getn{n=1000}) --> 1000
5 a = {}
6 print(table.getn(a)) --> 0
7 table.setn(a, 10000)
8 print(table.getn(a)) --> 10000
9 a = {n=10}
10 print(table.getn(a)) --> 10
11 table.setn(a, 10000)
12 print(table.getn(a)) --> 10000
デフォルトでは、setnとgetnは内部テーブルストレージテーブルのサイズを使用します.これはarrayを汚染する余分な元素を使用しないため、最もきれいな選択です.しかしながら、nドメインを使用する方法にもいくつかの利点がある.可変パラメータを持つ関数種では、Luaカーネルはこの方法を使用してarg配列のサイズを設定します.カーネルはライブラリに依存しないため、setnを使用できません.もう1つの利点は、arrayが作成されたときに、上記の例で見たように、彼のサイズを直接初期化できることです.setnとgetnを使用してarrayのサイズを操作するのは、ドメインnにサイズがあることを知っていても良い習慣です.tableライブラリのすべての関数(sort、concat、insertなど)はこの習慣に従います.実際には、setnを提供してドメインnの値を変更するのは、古いluaバージョンと互換性を持つためであり、この特性は将来のバージョンで変更される可能性があります.安全のため、この特性に依存すると仮定しないでください.getnを使用して配列サイズを取得し、setnを使用して配列サイズを設定してください.
19.2 tableライブラリの挿入/削除には、リストの任意の場所から要素を挿入および削除する関数があります.table.Insert関数はarray指定の位置に要素を挿入し、後ろの他のすべての要素を後ろに移動します.また、insertはarrayのサイズを変更します.例えば、aが配列{10,20,30}である場合、tableが呼び出される.Insert(a,1,15)後,aは{15,10,20,30}となる.よく使用される特殊な場合は、位置パラメータを持たずにinsertを呼び出すと、arrayの最後の位置に要素が挿入されます(したがって、要素の移動は必要ありません).次のコードは、プログラムに行ごとに独立し、すべての行をarrayに保存します.
1 a = {}
2 for line in io.lines() do
3 table.insert(a, line)
4 end
5 print(table.getn(a)) --> (number of lines read)
table.remove関数は、配列内の指定された位置の要素を削除し、この要素を返します.その後の要素はすべて前に移動し、配列のサイズが変わります.位置パラメータ呼び出しがない場合、arrayの最後の要素を削除します.この2つの関数を使用すると、スタック、キュー、および両端キューが容易に実現されます.構造をa={}に初期化できます.1つのpush操作はtableに等しい.insert(a,x);1つのpop操作はtableに等しい.remove(a).構造の他端に要素を挿入するにはtableを使用します.insert(a,1,x);削除要素用table.remove(a,1).最後の2つの操作は、要素を往復移動しなければならないため、特に有効ではありません.しかしながら,tableライブラリのこれらの関数はC実装を用いるため,小さな配列(数百要素)にとって効率に問題はない.
19.3ソート
もう一つの役に立つ関数はtableです.sort.彼には2つのパラメータがあります.要素を格納するarrayとソート関数です.ソート関数には2つのパラメータがあり、arrayでソートした最初のパラメータが2番目のパラメータの前にある場合は、ソート関数はtrueを返さなければなりません.ソート関数が指定されていない場合、sortはデフォルトのオペレータより小さいオペレータを使用して比較します.
一般的なエラーは、テーブルの下付きフィールドをソートしようとすることです.1つのテーブルでは、すべての下付き文字が1つの集合を構成しますが、無秩序です.彼らをソートしたい場合は、arrayにコピーしてこのarrayをソートする必要があります.例を見て、上記のソースファイルを読み取り、ソースファイルの各関数が定義されている場所の行番号を示すテーブルを作成したと仮定します.
1 lines = {
2 luaH_set = 10,
3 luaH_get = 24,
4 luaH_present = 48,
5 }
これらの関数名をアルファベット順で印刷したい場合は、pairsを使用してこのテーブルを巡回すると、関数名が表示される順序はランダムになります.しかし、これらの名前はテーブルのkeyであるため、直接ソートすることはできません.これらの関数名を配列内に配置すると、この配列をソートできます.まず、これらの関数名を保存する配列を作成し、ソートして結果を印刷する必要があります.
a = {}
for n in pairs(lines) do table.insert(a, n) end
table.sort(a)
for i,n in ipairs(a) do print(n) end
注意,Luaにとって配列も無秩序である.しかし、カウントする方法を知っているので、ソートされた下付きアクセス配列を使用すれば、ソートされた関数名を得ることができます.これがpairsではなくipairsを使用して配列を巡る理由です.前者はkeyの順序1,2,⋯⋯を用い,後者のテーブルの自然記憶順序である.より良い解決策があり、key値に基づいてこのテーブルを遍歴する反復子を書くことができます.オプションのパラメータfは、ソート方法を指定することができる.まず、ソートされたkeysを配列内に配置し、この配列を巡り、元のテーブルからkeyとvalueを返します.
function pairsByKeys (t, f)
local a = {}
for n in pairs(t) do table.insert(a, n) end
table.sort(a, f)
local i = 0 -- iterator variable
local iter = function () -- iterator function
i = i + 1
if a[i] == nil then return nil
else return a[i], t[a[i]]
end
end
return iter
end
この関数があれば、これらの関数名をアルファベット順に印刷しやすく、ループします.
for name, line in pairsByKeys(lines) do
print(name, line)
end
印刷結果:
luaH_get 24
luaH_present 48
luaH_set 10