在Lua中有一个PHP foreach等价物吗?

时间:2013-04-30 21:24:58

标签: php foreach lua lua-table

我已经习惯使用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

3 个答案:

答案 0 :(得分:2)

Lua在表上有2个内置迭代器。

pairs()迭代表中的所有条目,但没有特定的顺序:

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()会忽略非数字和非正整数键。

答案 1 :(得分: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创建自定义迭代器,例如{{1}},以迭代其他结构化数据类型。

答案 2 :(得分: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中的每一个上

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

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