*Luaで良く作る関数 ~table編~ [#x86ba688]

-[[table.empty>#table_empty]]
-[[table.elemn>#table_elemn]]
-[[table.in_key>#table_in_key]]
-[[table.in_value>#table_in_value]]
-[[table.keys>#table_keys]]
-[[table.values>#table_values]]
-[[table.map>#table_map]]
-[[table.filter>#table_filter]]
-[[table.dcopy>#table_deeepcopy_recursive]]
-[[table.scopy>#table_shallowcopy]]
-[[配列タイプのテーブルの高速複製>#talbe_numtype_shallowcopy]]
-[[table.merges>#table_merges]]
-[[table.unpack (Lua5.1用)>#table_unpack]]
-[[table.pack (Lua5.1用)>#table_pack]]
-[[table.set >#table_pack]]

&aname(table_empty);
**table.empty [#v0d29c8d]
#sh(lua){{
-- テーブルが空かどうかの判定
-- 引数にnilを渡しても「空」とみなす。
function table.empty(tbl)
    if tbl==nil then return true end
    return not next (tbl)
end
}}

&aname(table_elemn);
**table.elemn [#p6fb257c]
#sh(lua){{
-- テーブルに実際に存在する要素数(=num of elements)
-- 「#」や「table.getn」「table.maxn」ではテーブルの要素数は調べられないので必要となる。
function table.elemn(tbl)
    local n = 0
    for _ in pairs (tbl) do
        n = n + 1
    end
    return n
end
}}



&aname(table_in_key);
**table.in_key [#qe875447]
#sh(lua){{
-- 対象のテーブルのキーに、指定のkeyが存在するかどうか。
function table.in_key (tbl, key)
    for k, v in pairs (tbl) do
        if k==key then return true end
    end
    return false
end
}}


&aname(table_in_value);
**table.in_value [#zc99510e]
#sh(lua){{
-- 対象のテーブルの値に、指定のvalが存在するかどうか。
function table.in_value (tbl, val)
    for k, v in pairs (tbl) do
        if v==val then return true end
    end
    return false
end
}}

&aname(table_keys);
**table.keys [#pa87fd7a]
#sh(lua){{
-- 対象のテーブルのキーだけを抽出し、新たなテーブルとして得ます。
function table.keys (tbl)
    local u = {}
    for i, v in pairs (tbl) do
        table.insert (u, i)
    end
    return u
end
}}

&aname(table_values);
**table.values [#pa87fd7a]
#sh(lua){{
-- 対象のテーブルの値だけを抽出し、新たなテーブルとして得ます。
function table.values (tbl)
    local u = {}
    for i, v in pairs (tbl) do
        table.insert (u, v)
    end
    return u
end
}}


&aname(table_unique);
**table.unique [#w6b71518]
#sh(lua){{
-- 対象のテーブルの重複した値を除いた、新たなテーブルを返す。但し、キータイプの要素はそのまま残す。
function table.unique (tbl)
    local check = {}
    local res = {}

    -- 整数型だけユニーク化
    for i, v in ipairs(tbl) do
        if not(check[v]) then
            check[v] = true
            res[1+#res] = v
        end
    end

    -- キータイプはそのまま残す
    for k, v in pairs (tbl) do
        -- 整数以外
        if not (type(k)=="number" and k%1==0) then
            res[k] = v
        end
    end
    return res
end
}}

-使い方

#sh(lua){{
local tbl = {1, 2, 3, 3.0, 4.0, 5, 1}
local unique_tbl = table.unique(tbl) --> { 1, 2, 3, 4, 5 }

local tbl = {1,2,3,[1.5]=2, 3,2,1,2,3,3,5, a=5,b=5}
local unique_tbl = table.unique(tbl) --> { 1, 2, 3, 5, [1.5]=2, a=5, b=5 } キータイプはそのまま残り、それ以外の重複要素はカット
}}




&aname(table_map);
**table.map [#vf1c03dc]
#sh(lua){{
-- 対象のテーブルの各要素に対して、func(key, value)を実行し、関数実行結果を格納する。
-- 元のテーブルの値は変化せず、新たなテーブルが返される。
function table.map(tbl, func)
    local ret_tbl = {}
    for k, v in pairs (tbl) do
        ret_tbl[k] = func (k, v)
    end
    return ret_tbl
end
}}

-使い方

#sh(lua){{
local tbl = {1,2,k=4 }
local tbl2 = table.map( tbl , function(k, v) return v*v end ) -- 全ての要素を2乗した新たなテーブルを得る
}}


&aname(table_filter);
**table.filter [#ydfc1f1a]
#sh(lua){{
-- テーブル内で「func(k, v)を満たす」ものだけを新たなテーブルとして返す
-- func : テーブルtblの各判定に利用する関数
-- tbl : 対象のテーブル。(i型でもk型でも混合でもOK)
-- 戻り値 funcの条件によってフィルタリングされたテーブル。各要素はシャロウコピー
function table.filter(tbl, func)
    local res = {}
    for i, v in ipairs(tbl) do
        if func(i, v) then
            res[1+#res] = v --高速
        end
    end
 
    for k, v in pairs(tbl) do
        if func(k, v) then
            -- 整数以外がキーの要素
            if not (type(k)=="number" and k%1==0) then
                res[k] = v
            end
        end
    end
 
    return res
end
}}

-使い方

#sh(lua){{
local old_tbl = {1,10,30,a=20,b=30}

local new_tbl = table.filter(old_tbl, function(k, v) return v < 21 end)
-->  { 1, 10, b=20 }
}}

&aname(table_deeepcopy_recursive);
**table.dcopy [#za5236fa]
#sh(lua){{
-- テーブルの再帰的なディープコピー(deepcopy)を新たなテーブルとして返します。~
-- メタテーブルもコピーされます。
function table.dcopy(tbl)
    local orig_type = type(tbl)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in next, tbl, nil do
            copy[table.dcopy(orig_key)] = table.dcopy(orig_value)
        end
        setmetatable(copy, table.dcopy(getmetatable(tbl)))
    else -- number, string, boolean, etc
        copy = tbl
    end
    return copy
end

}}

-使い方

#sh(lua){{
local a = {1, 2, 3, { b=3,d=4, {c=a} } }
local b = {__iter = "abc", e = 33 }
setmetatable(a, b)

local c = table.dcopy(a)
}}


&aname(table_shallowcopy);
**table.scopy [#t1429da5]
#sh(lua){{
--テーブルのシャロウコピー(shallowcopy)を新たなテーブルとして返します。~
--メタテーブルはコピーされません。
function table.scopy(tbl)
    local orig_type = type(tbl)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in pairs(tbl) do
            copy[orig_key] = orig_value
        end
    else -- number, string, boolean, etc
        copy = tbl
    end
    return copy
end

}}


&aname(talbe_numtype_shallowcopy);
**配列タイプ(indexタイプ)のテーブルの高速複製 [#q682b8aa]
#sh(lua){{
--一番良く利用するNumberタイプのテーブルのシャロウコピーの場合、関数すら不要です。
local old_tbl = {5,8,"abc"}
local new_tbl = { unpack(old_tbl) } -- テーブルをリスト化してテーブルとすることでシャロウコピーとなる。5.2以降だと { table.unpack(old_tbl) }
}}

&aname(table_merges);
**table.merges [#wf2a3e76]
#sh(lua){{
-- ... :テーブル。2つ以上テーブルを渡す。
-- 整数indexの要素のものは、連結。シャロウコピー
-- キータイプものものは、重複していたら、後で渡したテーブルで上書き。
-- 返り値 : 連結された新たなテーブル
function table.merges (...)
    local r = {}
    for _, l in ipairs ({...}) do
        if type(l) == "table" then
            -- 整数がキーの要素
            for _, v in ipairs (l) do
                table.insert (r, v)
            end
            -- 整数以外がキーの要素
            for k, v in pairs (l) do
                if not (type(k)=="number" and k%1==0) then
                    r[k] = v
                end
            end
        end
    end

    return r
end
}}

-使い方

#sh(lua){{
local mergetbl = table.merges( { 1,2,3,k=5,{1,2} }, { 10,2 }, { a=50,k=10 } )

-- > { 1, 2, 3, { 1, 2 }, 10, 2, a=50, k=10 }
}}

&aname(table_unpack);
**table.unpack (Lua5.1用) [#d37acffe]
#sh(lua){{
-- lua5.2と同じ記述が可能なように、unpackをtable.unpackに複製
if not table.unpack then
    table.unpack = unpack
end
}}

&aname(table_pack);
**table.pack (Lua5.1用) [#t2b7b166]
#sh(lua){{
-- lua5.2と同じ記述が可能なように、table.packを作成
if not table.pack then
    function table.pack (...) 
        return { n=select('#',...), ...} 
    end
end
}}

&aname(table_set);
**table.set [#k9cae1c8]
#sh(lua){{
--簡易なSet化の例
--ハッシュだとvalueが必要なので、value抜きで初期化できるものを簡易に作る
function table.set (list)
   local set = {}
   for _, l in ipairs(list) do set[l] = true end
    return set
end
}}
-使い方
-使い方~

#sh(lua){{
-- 初期化の際に table.set{["while"]=true, ["end"]=true, ["function"]=true, ["local"]=true, } としなくて良い
reserved = table.set{"while", "end", "function", "local", }
}}

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS