意在越界选择数组元素

假设有如下数组:

a = {"a", "b", "c"}

使用 a[3] 可以访问到 c。但是我该如何让字符串“无限重复”(同时仍然只有元素)?例如:

a[4] --将返回 nil,但我需要它返回“a”,因为 4 是 3(数组末尾)+1(我需要的元素)。

问题:

如果 a[] 由 3 个元素组成,我该如何使 a[4] 返回与 a[1] 相同的值呢?

点赞
用户6834680
用户6834680

你可以确保所使用的键在适当的范围内,或者实现 __index 元方法将此逻辑移入到表 a 的元表中。这样,当有人访问表中的无效键时,你就能告诉 Lua 返回什么。参见:http://lua-users.org/wiki/MetamethodsTutorial

local function circle(arr)
   setmetatable(arr, {__index =
      function(t, k)
         if type(k) == "number" and #t > 0 then
            return rawget(t, (k-1) % #t + 1)
         end
      end
   })
end

local a = {"a", "b", "c"}
circle(a)

for j = -10, 10 do
   print(j, a[j])
end
2016-12-12 14:27:51
用户3735873
用户3735873

这只是 Egor Skriptunoff 正确答案的略微变化,因为我不想保留格式的话就留下它的注释。

在我看来,这个变化让表的创建简单化为一个清晰的语句,也使用了同一个表作为元表的小优化。

local
function circle(arr)
  function arr.__index(t, k)
    if type(k) == 'number' and #t > 0 then
      return rawget(t, (k-1) % #t + 1)
    end
  end
  return setmetatable(arr,arr)
end

local a = circle {'a', 'b', 'c'}

for j = -10, 10 do print(j, a[j]) end
2016-12-13 22:01:57