能否无需for循环直接将string.gmatch结果写入Lua表?
能否无需for循环直接将string.gmatch的所有输出值写入表中?
导出字符串
!Elwynn Forest:Player-3674-0B18B930;false;0;false*!Player-3674-0B18B930:1;Rasudruid;Murky;500;0;1*!currentRound:1*!turnStatus:roll*!currentTurn:1*!
当前使用的Lua代码
local function loadGameFromString(importString) for exportValue in string.gmatch(importString, '!([^!]+)*') do print(exportValue) local prefix = string.match(exportValue, '([^:]+):') local dataValues = {} for data in string.gmatch(exportValue, '[:;]+([^:^;]+)') do table.insert(dataValues, data) end if propertyCards[prefix] then print("card") elseif string.find(prefix, "Player") then playerData[prefix] = { playerNumber = dataValues[1], name = dataValues[2], figure = dataValues[3], money = dataValues[4] } else print("gameData") end end end
需求说明
当前需用多行代码遍历匹配项,希望在保留原有数据填充功能(如下列写法)的前提下,用更少行数实现直接写入表的操作:
gameData = { name = dataValues[1], state = dataValues[2] }
解决方案
在Lua中,无法完全移除处理每个匹配项的循环(因为需要逐个解析并填充到对应表中),但可以大幅简化dataValues的收集逻辑,用更紧凑的代码实现:
优化后的完整代码
local function loadGameFromString(importString) for exportValue in string.gmatch(importString, '!([^!]+)') do print(exportValue) local prefix = exportValue:match('([^:]+):') -- 一行完成所有匹配数据的收集,替代原有的多行循环 local dataValues = {} for v in exportValue:gmatch('[:;]+([^:;]+)') do dataValues[#dataValues+1] = v end if propertyCards[prefix] then print("card") elseif prefix:find("Player") then playerData[prefix] = { playerNumber = dataValues[1], name = dataValues[2], figure = dataValues[3], money = dataValues[4] } else -- 示例:填充gameData的逻辑,保留索引式写法 gameData[prefix] = {value = dataValues[1]} print("gameData") end end end
进一步简化dataValues收集(可选)
如果追求极致行数精简,可通过匿名函数调用一行完成dataValues的初始化与填充:
local dataValues = (function(t) for v in exportValue:gmatch('[:;]+([^:;]+)') do t[#t+1] = v end return t end)({})
该写法虽紧凑但可读性稍降,可按需选择。
优化点说明
- 用Lua字符串方法语法(
exportValue:gmatch)替代string.gmatch(exportValue),减少代码冗余。 - 将
dataValues的收集循环压缩为一行,直接通过索引赋值替代table.insert。 - 完全保留了原有
dataValues[N]索引式填充表的逻辑,符合需求。
内容的提问来源于stack exchange,提问作者Lars
相关产品推荐
相关产品推荐

