【问题标题】:Select array element out of bounds on purpose故意选择超出范围的数组元素
【发布时间】:2017-04-27 08:32:56
【问题描述】:

假设如下数组:

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

使用a[3],我可以访问c。但是如何使字符串“永远重复”(虽然它仍然只有元素)?示例:

a[4] --will return nil, but I need to to return "a", because 4 is 3 (end of array) + 1 (the element I need).

问题:

如果 a[] 包含 3 个元素,我如何让 a[4] 返回与 a[1] 相同的值?

【问题讨论】:

  • 顺便说一句——表不是数组。一个表可能包含一个序列,也可能不包含。您的“由 3 个元素组成”似乎是 sequence length 的一个示例。只要您的表包含一个序列,使用#t 的算法就可以工作。您也可以添加不是正整数的键。添加或删除正整数键时,不要破坏序列。

标签: arrays lua


【解决方案1】:

您可以确保您使用的密钥在适当的范围内,或者通过实现__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

【讨论】:

  • @Piglet - 也许,你应该锻炼你的打字速度:-)
  • 这很好用,如果j 是文字数字也有效。谢谢!
【解决方案2】:

这只是 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-25
    • 2016-12-23
    • 1970-01-01
    • 2013-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多