操作表键

Manipulating table key

提问人:user3204810 提问时间:10/16/2023 最后编辑:user3204810 更新时间:10/17/2023 访问量:79

问:

此表的结构如下:

local t = {
        ["track"] = "one#two#three",
        {
            ["track"] = "four"
        }, -- [1]
}

第一步是将“track”键替换为“aura”键。为此,我创建了这个函数

local function probe(tbl)
    for k, v in pairs(tbl) do
        if type(v) == "table" then
            probe(v)
        elseif type(v) == "string" and k == "track" then
            tbl["aura"] = tbl[k]
            tbl[k] = nil
        end
    end
end

运行命令 the table becomesprobe(t)

{
      ["aura"] = "one#two#three",
      {
          ["aura"] = "four",
      }, -- [1]
}

第二步是创建与字符串 “one#two#three” 中的标记一样多的 { [“aura”] = word } 形式的表。为此,我创建了函数

local function updateDB(tbl, depth)
    if depth > 0 then    
        local d = depth    
        for k, v in pairs(tbl) do
            if type(v) ~= 'table' then                
                if k == 'aura' then
                    local count = 1
                    for word in v:gmatch(("[^%s]+"):format("#")) do
                        tbl[count] = { ["aura"] = word }
                        count = count + 1
                    end
                    tbl[k] = nil    
                end
            else 
                d = d - 1
                updateDB(v, d)
            end
        end
    end
end

我得到的最后一张桌子是这个

{
      {
          aura= "one",
      }, -- [1]
      {
          aura= "two",
      }, -- [2]
      {
          aura= "three",
      }, -- [3]
}

但是“四”值消失了

lua 数据操作 lua-table

评论

1赞 Luatic 10/17/2023
在遍历表时,不得添加新键。您的函数当前表现出未定义的行为。probe
0赞 user3204810 10/17/2023
该函数将“track”键重命名为“aura”键
1赞 Luatic 10/17/2023
是的,你不能(如,不允许,它通常可以正常工作,但是当触发重新哈希时你可能会遇到问题)在迭代表时这样做。你应该在循环之外进行。
1赞 Luatic 10/17/2023
在评论中发帖有点尴尬,但像.也可能:)效率略高local function probe(tbl) for k, v in pairs(tbl) do if type(v) == "table" then probe(v) end end if type(tbl.track == "string") then tbl.aura = tbl.track; tbl.track = nil end end
1赞 Luatic 10/17/2023
哎呀,看来我那里有错别字。它应该是 ,否则你得到的永远是字符串 ,这是真的。type(tbl.track) == "string"type(tbl.track == "string")"boolean"

答:

2赞 shingo 10/16/2023 #1

因为您开始从 1 插入元素。要将元素插入到空插槽中,可以使用 或 .t[#t+1]table.insert

--local count = 1
for word in v:gmatch(("[^%s]+"):format("#")) do
    tbl[#tbl+1] = { ["aura"] = word }
    --count = count + 1
end
--local count = 1
for word in v:gmatch(("[^%s]+"):format("#")) do
    table.insert(tbl, { ["aura"] = word })
    --count = count + 1
end
1赞 darkfrei 10/16/2023 #2

请参阅此字符串分隔符:https://stackoverflow.com/a/1647577/12968803

链接的代码在分隔符(也是两端)之间采用字符串。

更新: 该函数返回列表,而不是迭代器:

function string:split(pat)
    pat = pat or '%s+'
    local result = {}
    local st, g = 1, self:gmatch("()("..pat..")")
    local function getter(segs, seps, sep, cap1, ...)
        st = sep and seps + #sep
        table.insert(result, self:sub(segs, (seps or 0) - 1))
        return cap1 or sep, ...
    end
    local function iterate()
        if st then
            getter(st, g())
        end
        return result
    end
    while st do
        iterate()
    end
    return result
end

用法:

local str = "one#two#three"
local list = str:split("#")
for i, v in ipairs (list) do
    print (i, v)
end

结果:

1   one
2   two
3   three
0赞 user3204810 10/17/2023 #3

固定

步骤一:

local t = {
        ["track"] = "one#two#three",
        {
            ["track"] = "four"
        }, -- [1]
}

local function probe(tbl) -- Rename "track" to "aura"
    for k, v in pairs(tbl) do 
        if type(v) == "table" then 
            probe(v)
        end 
    end
    if tbl.track then 
        tbl.aura = tbl.track
        tbl.track = nil 
    end
end

probe(t):now 表变为

{
      ["aura"] = "one#two#three",
      {
          ["aura"] = "four",
      }, -- [1]
}

第二步:

function updateDB(tbl, depth) 
    if depth > 0 then        
        for k, v in pairs(tbl) do
            if type(v) ~= 'table' then                
                if k == 'track' then
                    local count = 1
                    for word in v:gmatch(("[^%s]+"):format("#")) do
                        table.insert(tbl,{ ["aura"] = word })
                        count = count + 1
                    end
                    tbl[k] = nil    
                end
            else 
                updateDB(v, depth-1)
            end
        end
    end
end

updateDB(t,1):现在表格变为

{
      {
          aura= "one",
      }, -- [1]
      {
          aura= "two",
      }, -- [2]
      {
          aura= "three",
      }, -- [3]
      {
          aura= "four",
      }, -- [3]
}