Forcing order of a 'for' loop

ww2commander

Emperor
Joined
Aug 23, 2003
Messages
1,243
Location
Australia
How do you force lua to loop through a table in order of entries.

In the below example, the result is 1942, 1941, 1945, 1943, 1944 when I run the associate code snippet!

I want it to list items in the exact order they appear in the table...obvious reason is that they represent date order.

Code:
g_PointThresholds = {
["HANDICAP_SETTLER"] =	{
	["1941"] = {StartTurn = 0, EndTurn = 27, Points = 0,},
	["1942"] = {StartTurn = 28, EndTurn = 79, Points = 0,},
	["1943"] = {StartTurn = 80, EndTurn = 131, Points = 0,},
	["1944"] = {StartTurn = 132, EndTurn = 0, Points = 0,},
	["1945"] = {StartTurn = 185, EndTurn = 206, Points = 0,},
								},
}


for year, thresholdData in pairs (g_PointThresholds[playerHandicapType]) do
	--do process code here
end

Any help appreciated
 
Won't work as ipairs() iterates over index-value pairs of a table. A Lua table always starts from an index of 1 and entries are contiguous. Any other entries are actually hash (ie key-value) pairs, and these are exclude from ipairs() (unless they happen to fall within the contiguous range)

If the start and end year are known and contiguous, you could convert the keys to ints and use

for year = 1941, 1945 do
local thresholdData = g_PointThresholds[playerHandicapType][year]

--do process code here
end
 
You're right, forgot ipairs doesnt work with sparse arrays :crazyeye:
Another way to do it which does not require known consecutive years would be:
g_PointThresholds = {
["HANDICAP_SETTLER"] = {
{ Year=1941, StartTurn = 0, EndTurn = 27, Points = 0 },
{ Year=1942, StartTurn = 28, EndTurn = 27, Points = 0 },
{ Year=1943, StartTurn = 80, EndTurn = 131, Points = 0 },
{ Year=1944, StartTurn = 132, EndTurn = 184, Points = 0 },
{ Year=1945, StartTurn = 185, EndTurn = 206, Points = 0 },
},
}
for i, thresholdData in ipairs (g_PointThresholds[playerHandicapType]) do
--do process code here
end
 
You're right, forgot ipairs doesnt work with sparse arrays :crazyeye:
Another way to do it which does not require known consecutive years would be:
g_PointThresholds = {
["HANDICAP_SETTLER"] = {
{ Year=1941, StartTurn = 0, EndTurn = 27, Points = 0 },
{ Year=1942, StartTurn = 28, EndTurn = 27, Points = 0 },
{ Year=1943, StartTurn = 80, EndTurn = 131, Points = 0 },
{ Year=1944, StartTurn = 132, EndTurn = 184, Points = 0 },
{ Year=1945, StartTurn = 185, EndTurn = 206, Points = 0 },
},
}
for i, thresholdData in ipairs (g_PointThresholds[playerHandicapType]) do
--do process code here
end

If you can, I was under the impression that using pairs was preferable to ipairs for performance reasons?
 
for performance reasons?

Once round a loop of a few elements is going to make no noticeable difference how you do it. Several thousand elements possibly.
 
Performance difference between pairs and ipairs is tiny, so only noticeable if called a lot (e.g., if called for every plot for every turn).

However, I have a personal distaste for ipairs. You can always replace this:

Code:
for i, v in ipairs(table) do
	<loop code>
end

with this:

Code:
for i = 1, #table do
	local v = table[i]
	<loop code>
end

The latter is faster than either pairs or ipairs (even more so if you know the size of table already so don't need to use #table). But does it matter? In the vast majority of situations: no.
 
Back
Top Bottom