0

我已经习惯了使用 foreach 语句在 PHP 中编程:

Lua中是否有与此等价的功能?

谢谢!

相关部分:

function renderobjects()
    o1 = object:new{x = 30, y = 30, roomx = 0, roomy = 0, symbol = "t", name = "Tree"}
    o2 = object:new{x = 47, y = 60, roomx = 0, roomy = 0, symbol = "w", name = "Water"}
    o3 = object:new{x = 42, y = 30, roomx = 1, roomy = 0, symbol = "C", name = "Cactus"}
    table.insert(o1, objects)
    table.insert(o2, objects)
    table.insert(o3, objects)
    table.foreachi(objects, object) do
        if player.roomx = object.roomx and player.roomy = object.roomy then
            rb.putsxy(object.x, object.y, symbol)
        end
    end
end

local object = {
    x = 30,
    y = 30,
    roomx = 0,
    roomy = 0,
    name = "Unknown Object",
    touchingplayer = false,
    symbol = "u"
}

function object:new (o)
    o = o or {}   -- create object if user does not provide one
    setmetatable(o, self)
    self.__index = self
    return o
end
4

3 回答 3

2

Lua 有 2 个内置的表迭代器。

pair() 遍历表中的所有条目,但没有特定的顺序:

t={monday=1, tuesday=2, wednesday=3, thursday=4, friday=5, saturday=6, sunday=0, [7]="fooday"}
for key, value in pairs(t) do                       
   print(value, key)
end

输出:

0   sunday
fooday  7
2   tuesday
3   wednesday
5   friday
4   thursday
6   saturday
1   monday

ipairs() 使用正整数键迭代表条目,并用于按顺序迭代列表。

l={'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', not_a_number='fooday', [0]='today', [-1]='yesterday' }
for key, value in ipairs(l) do                                                                         
  print(key, value)
end

输出:

1   monday
2   tuesday
3   wednesday
4   thursday
5   friday
6   saturday
7   sunday

请注意, ipairs() 忽略非数字和非正整数键。

于 2013-04-30T21:30:01.873 回答
1

你的例子很简单:

function renderobjects()
    -- ... some of your code elided
    for _,object in ipairs(objects) do
        if player.roomx == object.roomx and player.roomy == object.roomy then
            rb.putsxy(object.x, object.y, object.symbol)
        end
    end
end

注意==不在=比较中。

在这种情况下ipairs有效,因为您使用objects的是数组。

您可以创建自定义迭代器,例如ipairs使用通用for语句迭代其他结构化数据类型。

于 2013-04-30T22:43:42.080 回答
0

因此,假设这objects是一个全局的(或至少在 的词汇范围之外renderobjects),您可以像这样重写renderobjects

-- Master list of objects to be rendered and processed
objects = {}

-- Create some objects to render
objects[#objects+1] = object:new{
    x = 30, y = 30, 
    roomx = 0, roomy = 0, 
    symbol = "t", 
    name = "Tree",
}
objects[#objects+1] = object:new{
    x = 47, y = 60, 
    roomx = 0, roomy = 0, 
    symbol = "w", 
    name = "Water",
}
objects[#objects+1] = object:new{
    x = 42, y = 30, 
    roomx = 1, roomy = 0, 
    symbol = "C", 
    name = "Cactus",
}

-- Render the objects in the global list objects.
-- with some special care for player and using the
-- global rb to draw
function renderobjects()
    for _,obj in ipairs(objects) do
        if player.roomx == obj.roomx 
            and player.roomy == obj.roomy then                        
            rb.putsxy(obj.x, obj.y, obj.symbol)
        end
    end
end

这使用标准习语来扩展表中的列表,使用#运算符来学习列表的当前长度。这个成语在效果上类似于table.insert(),但通常更快。请注意,您的代码具有table.insert反转的参数,因此将(可能为空的)全局对象列表附加到每个o1o2o3.

我还将少数演示对象的初始化从渲染调用中分离出来。他们不去那里......

我使用泛型构造重写了循环,并使用foripairs. 而不是这样写,因为for _,obj in ipairs(objects) do它可以写成for i=1,#objects do local obj = objects[i]. 后者稍快一些,因为它不涉及每次循环迭代的函数调用,但对某些读者来说可能不太清楚。无论哪种方式,表达的清晰度都应该胜过所有其他问题,直到您有分析数据表明这是一个瓶颈。

于 2013-04-30T22:39:40.797 回答