如何同时迭代两个表格

我对 Lua 不是很熟练,在试图同时迭代两个表时遇到了麻烦。下面的代码演示了我想要做的事情。一些解释:

我有两个字符串

  1. slug —— 一个形如 a/b/c 的字符串。
  2. holds —— 另一个形如 x/y/z 的字符串。

我的做法

  1. / 字符将两个字符串分割成两个表。
  2. 迭代 slug 表,并将其每个部分放入另一个表 slugs 中。
  3. 在这样做的同时,如果 slug 中的一个元素包含连字符,则 slugs 表不只是一个条目,而是两个条目。因此,如果 slughello/world/stackoverflow,则会生成一个 slugs 表,其中包含三个元素:hello、world 和 stackoverflow。
  4. 但是,hello/world/stack-overflow 会生成一个包含四个元素的表:hello、world、stack 和 overflow。

问题所在

现在我输出另一个表 parts,该表的索引是原始 hold 表中的条目。如果没有连字符分割,那么就会有一一对应的关系,parts 就包含:

{a:hello,b:world,c:stackoverflow}

然而,如果有连字符,如 hello\world\stack-overflowparts 就包含

{a:hello,b:world,c:stack}

Overflow 没有出现。我怀疑可以通过同时迭代两个表来避免这个问题。但是,我无法理解如何/是否可以做到这一点。我试图遵循 这个教程 中的笔记,但没有取得多少进展。

在理想的情况下,我希望能够即时修改 hold 表,以便在检测到连字符时,其对应的 slug 表中的位置 c 包含 {a,b,c0,c1}

如果这个修改生效,那么输出的 parts 表就会包含

{a:hello,b:world,c0:stack,c1:overflow}

我应该提到我正在使用 Lua 5.1,没有升级到更高版本的选项。

function explode(div,str)
 if (div=='') then return false end
 local pos,arr = 0,{};
 local part = "";
 for st,sp in function() return string.find(str,div,pos,true) end do
  part = string.sub(str,pos,st-1);
  if ((0 < string.len(part)) and ("rest" ~= part)) then
   table.insert(arr,part);
  end;
  pos = sp + 1
 end
 table.insert(arr,string.sub(str,pos))
 return arr
end;

function resolveParts(slug,holds)
 local parts,slugs = {},{};

 for i,s in pairs(slug) do
  if (string.find(s,'%-')) then
     s = explode('-',s);
     table.insert(slugs,s[1]);
     table.insert(slugs,s[2]);
  else
     table.insert(slugs,s);
    end;
end;

--slugs 包含 **四个** 元素,因为 over-flow 被分成了两部分
for i,hold in pairs(holds) do
 parts[hold] = slugs[i];
end;
--在“old”holds表上迭代将导致在“parts”中丢失一个条目
local slug = explode('/',"hello/stack/over-flow");
local holds = explode("/","a/b/c");
-- slug & hold 都是包含 3 个元素的表
local parts = resolveParts(slug,holds);
点赞
用户2726734
用户2726734

使用 @EtanReisner 的建议,将连字符的值保留在表格中。通过在数据结构中显式地表示关系,如 c0、c1,可以避免将键与彼此关联的问题。在字符串中编码任何内容会在以后使用编码的关系(混乱慈强的代码)或者在输入不同的情况下(如 hold='c/c5/a/a3')导致问题时,要求出问题。

function split(str, sep)
  local parts = {}
  for m in str:gmatch('[^' .. sep .. ']+') do
    parts[#parts + 1] = m
  end
  return parts
end

function join(ks, vs)
  local t = {}
  for i, k in pairs(ks) do
    t[k] = vs[i]
  end
  return t
end

slugs = split('hello/stack/over-flow', '/')
holds = split('a/b/c', '/')
parts = join(holds, slugs)

-- 检测连字符并重新分割
for k, v in pairs(parts) do
  if v:find('-') then
    parts[k] = split(v, '-')
  end
end

-- 在使用 parts 时检测表格或字符串
for k, v in pairs(parts) do
  if type(v) == "table" then
    for i, vi in ipairs(v) do
      print(k .. i, vi)
    end
  else
    print(k, v)
  end
end

输出结果如下:

b   stack
c1  over
c2  flow
a   hello
2015-07-09 16:00:50