Ok. I get that
So if ipairs basically does the same job as a basic for loop, why does it exist? Is there a specific function it can apply to, where you'd need to specifically use it, rather than something like the for loop you illustrated?
Card Game
Re: Card Game
I don't see any practical difference; the only thing I can think is perhaps there is a speed difference between regular for and ipairs. I know there is a difference between ipairs and pairs (with pairs being faster), but I am not certain about regular for and ipairs.
Maybe its like how Python programmers say do it the "Python way." ipairs is the Lua way.
Maybe its like how Python programmers say do it the "Python way." ipairs is the Lua way.
Re: Card Game
Kikito, in his tile tutorial, says that the regular for is faster
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
- bartbes
- Sex machine
- Posts: 4946
- Joined: Fri Aug 29, 2008 10:35 am
- Location: The Netherlands
- Contact:
Re: Card Game
I haven't got the statistics, but yes, it is. ipairs is more idiomatic however, and in general people don't really care about those tiny speed-ups (and you shouldn't, either). There is, however, a difference, ipairs doesn't have to go to #t (with t being the table), since that can include embedded nils.
Example:
Example:
Code: Select all
print(#{1, nil, 2}) --> 3
local counter = 0
for i, v in ipairs{1, nil, 2} do
counter = counter + 1
end
print(counter) --> 1
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: Card Game
ipairs, for a while, was going to be removed from Lua 5.2 . Or there were rumors about it; I didn't pay too much attention to them. At the end, it was kept in Lua, and I think that was a good decision.
First of all, ipairs is not exactly like pairs. pairs doesn't give any guarantee about the order in which the elements of the array are parsed. I think right now, it *does* respect the numerical order, but that's an implementation detail; other implementations, like LuaJIT or Lua 5.3, could change the implementation so that it didn't respect the order, and that would still be compatible with the Lua spec. My point is, you can't make the assumption in your code when using pairs.
The obvious conclusion to all this is - ok, I'll use a numeric for then. So, why do I need ipairs?
Well, the answer is, yeah, use a numeric for when you can. But in some occasions you can't. Sometimes you just need an iterator function.
Consider the typical copy function:
As far as I know, in the standard 5.1 Lua, this function works with both hash-like tables and array-like tables - but this is an implementation detail; pairs is not guaranteed to follow the numerical order in keys, so in the next version of Lua, or in an alternative implementation, it might copy the keys in a different order (so it would not generate an array, but a hash). Without ipairs, you would end up needing two different implementations; one for copying arrays, using the numeric for, which is guaranteed to follow the numeric keys, and another one for the rest.
But with ipairs, you can do this:
This version of the function accepts a second (optional) parameter called "iterator". By default, it is pairs. But you can set it to ipairs if you want:
So, you can get numerical order, if you need it.
Setting the iterator as an optional parameter has another benefit: you can example, create an iterator function that returns only the even members of the array - or the members of the array in reverse order. Or only the members of a hash whose key starts with "a". And the copy function will work with those, too:
So, this is the reason I imagine ipairs exist: When you are developing a function that parses tables, sometimes,you want to let the users of that function specify how they want to parse a table - like with the iterator parameter. And on the other hand, when you are using that function, you may want to have the guarantee that the numeric values are parsed in order. Granted - very rare case. But possible.
At least that is my opinion. I haven't checked that on the Lua mailing list or anything.
That's a very good question. I thought about it myself, and found a possible explanation.tdc5013 wrote:So if ipairs basically does the same job as a basic for loop, why does it exist? Is there a specific function it can apply to, where you'd need to specifically use it, rather than something like the for loop you illustrated?
First of all, ipairs is not exactly like pairs. pairs doesn't give any guarantee about the order in which the elements of the array are parsed. I think right now, it *does* respect the numerical order, but that's an implementation detail; other implementations, like LuaJIT or Lua 5.3, could change the implementation so that it didn't respect the order, and that would still be compatible with the Lua spec. My point is, you can't make the assumption in your code when using pairs.
The obvious conclusion to all this is - ok, I'll use a numeric for then. So, why do I need ipairs?
Well, the answer is, yeah, use a numeric for when you can. But in some occasions you can't. Sometimes you just need an iterator function.
Consider the typical copy function:
Code: Select all
function copy(tbl)
local result = {}
for k,v in pairs(tbl) result[k] = v end
return result
end
But with ipairs, you can do this:
Code: Select all
function copy(tbl, iterator)
iterator = iterator or pairs
local result = {}
for k,v in iterator(tbl) result[k] = v end
return result
end
Code: Select all
t1 = {1,2,3}
t2 = copy(t1, ipairs)
Setting the iterator as an optional parameter has another benefit: you can example, create an iterator function that returns only the even members of the array - or the members of the array in reverse order. Or only the members of a hash whose key starts with "a". And the copy function will work with those, too:
Code: Select all
t3 = copy(t1, evenpairs)
t4 = copy(t1, reverseipairs)
t5 = copy(t1, keystartpairs("a"))
At least that is my opinion. I haven't checked that on the Lua mailing list or anything.
Last edited by kikito on Sun Feb 12, 2012 11:26 am, edited 1 time in total.
When I write def I mean function.
- Robin
- The Omniscient
- Posts: 6506
- Joined: Fri Feb 20, 2009 4:29 pm
- Location: The Netherlands
- Contact:
Re: Card Game
What I like about ipairs is that it reduces the "housekeeping" you have to do. Compare:
and:
to:
In the last, you don't have to index your table or declare an extra local variable all the time, which could distract from the algorithm inside the loop.
Code: Select all
for i = 1, #t do
--.... use i and t[i] here
end
Code: Select all
for i = 1, #t do
local v = t[i]
--.... use i and v here
end
Code: Select all
for i, v in ipairs(t) do
--.... use i and v here
end
Help us help you: attach a .love.
Re: Card Game
Thanks, I understand this now, I think. Slightly different ways of implementation, but if i needed ipairs has a few more functions that For doesn't (even though it's possible to program them with a For loop, it would require a few more lines of code).
Who is online
Users browsing this forum: No registered users and 3 guests