-- テーブルに実際に存在する要素数(=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
-- 対象のテーブルの重複した値を除いた、新たなテーブルを返す。但し、キータイプの要素はそのまま残す。
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
-- 対象のテーブルの各要素に対して、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
使い方
local tbl = {1,2,k=4 }
local tbl2 = table.map( tbl , function(k, v) return v*v end ) -- 全ての要素を2乗した新たなテーブルを得る
-- テーブル内で「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
使い方
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 }
-- テーブルの再帰的なディープコピー(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
使い方
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)
--テーブルのシャロウコピー(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
-- ... :テーブル。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
--簡易なSet化の例
--ハッシュだとvalueが必要なので、value抜きで初期化できるものを簡易に作る
function table.set (list)
local set = {}
for _, l in ipairs(list) do set[l] = true end
return set
end