Lua:大小写不敏感引用table键及递归设置元表

Lua:大小写不敏感引用table键及递归设置元表

Lua中table的键是区分大小写的,即:

local t = {}
t.a = "a"
print(t.A) -- nil

有时候希望可以大小写不敏感地访问、引用table的键,可以通过设置元表实现:

local t = {}
t.a = "a"
t.B = "B"
t.c = "c"

local mt = {}
mt.__index = function(t, k)
	local v
	-- t中含大量键时开销极大
	for tk, tv in pairs(t) do
		-- 大小写不敏感比较键
		if string.lower(tk) == string.lower(k) then
			v = tv
			break
		end
	end
	return v
end

setmetatable(t, mt)

-- 正常调用
print(t.a) -- a
-- 小写转大写调用
print(t.b) -- B
-- 大写转小写调用
print(t.C) -- c

有两个问题:

1.这样的代码仅适用于功能,不适用于性能。

当t中包含的键非常多时,而我们恰好触发原方法__index,就导致一次遍历。

这样做开销极大,在上量跑压力时有很大的问题。(耗费大量CPU做遍历)

2.只针对t有效,t的子孙table,没有设置元表,仍然大小写敏感。

于是我们需要“递归设置元表”。


我这里指的是,将一个元表设置到某个table,以及table中所有的子孙table。

local mt = {}
mt.__index = function(t, k)
	local v
	-- t中含大量键时开销极大
	for tk, tv in pairs(t) do
		-- 大小写不敏感比较键
		if string.lower(tk) == string.lower(k) then
			v = tv
			break
		end
	end
	return v
end

-- 递归设置元表
function recurrence_setmetatable(t, mt)
	if type(t) ~= "table" then
		return
	end

	-- 设置table元表
	setmetatable(t, mt)

	-- 递归table设置子元表
	for _, tv in pairs(t) do
		if type(tv) == "table" then
			recurrence_setmetatable(tv, mt)
		end
	end
end

local t = {}
t.test1024 = {}
t.test1024.test1280 = {}
t.test1024.test1280.key = "value"
t.a = "a"

recurrence_setmetatable(t, mt)

print(t.TEST1024.TEST1280.KEY) -- value
print(t.a) -- a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值