If i try to output this table, they are looped through in the false order:
local letters = {DIN1="hi", AIN1= "my", AIN2 ="name", DIN2="is"}
for name, value in pairs(letters) do
print(name,value)
end
Expected Output:
DIN1 hi
AIN1 my
AIN2 name
DIN2 is
Output:
AIN1 my
DIN2 is
DIN1 hi
AIN2 name
How can i code it so that the for loop runs through the tables actual order? (The order how it was defined)
Edit: I don't need the alphabetic order, but the same order as in the definition of the table.
Edit: I need to have the key AND the value printed. In the answer "Lua in pairs with same order as it's written" there will be only indexnumber and value printed
You may utilize integer part of the table to store keys in order:
function add(t, k, v, ...)
if k ~= nil then
t[k] = v
t[#t+1] = k
return add(t, ...)
end
return t
end
t = add({ }, "A", "hi", "B", "my", "C", "name", "D", "is")
for i,k in ipairs(t) do
local v = t[k]
print(k, v)
end
Of course, this assumes that integer keys are not used by anything except add.
insert(t, k, v) and remove(t, k) left as an exercise to the reader.
EDIT:
Ellipsis (dots) in add function allow passing as many arguments as needed to set many kv-pairs at once. Without that, we would be only able to set one pair per call, like add(t, "A", "hi"). Function definition add(t, k, v, ...) assigns first three arguments to t, k, v and leaves others untouched. Then add processes first pair (t[k]=v) and recurses with the rest ... of arguments.
t k v ...
level 1: (t, "A", "hi", "B", "my", "C", "name", "D", "is")
level 2: (t, <- "B", "my", "C", "name", "D", "is")
level 3: (t, <- "C", "name", "D", "is")
level 4: (t, <- "D", "is")
level 5: (t, <- )
At level 5, k and v take nils, because argument list is too short, and recursion stops.
The Lua-users wiki has a page that addresses this particular problem.
Quoting the code from that page:
--[[
Ordered table iterator, allow to iterate on the natural order of the keys of a
table.
Example:
]]
function __genOrderedIndex( t )
local orderedIndex = {}
for key in pairs(t) do
table.insert( orderedIndex, key )
end
table.sort( orderedIndex )
return orderedIndex
end
function orderedNext(t, state)
-- Equivalent of the next function, but returns the keys in the alphabetic
-- order. We use a temporary ordered key table that is stored in the
-- table being iterated.
key = nil
--print("orderedNext: state = "..tostring(state) )
if state == nil then
-- the first time, generate the index
t.__orderedIndex = __genOrderedIndex( t )
key = t.__orderedIndex[1]
else
-- fetch the next value
for i = 1,table.getn(t.__orderedIndex) do
if t.__orderedIndex[i] == state then
key = t.__orderedIndex[i+1]
end
end
end
if key then
return key, t[key]
end
-- no more value to return, cleanup
t.__orderedIndex = nil
return
end
function orderedPairs(t)
-- Equivalent of the pairs() function on tables. Allows to iterate
-- in order
return orderedNext, t, nil
end
Not that natural order of the keys here means that you start with the smallest key (as if determined by a < b style comparisons), which is not necessarily the key that you write first in your code when filling the table (determining the latter is way more complicated and way less reasonable).
You can then simply use the orderedPairs function as a drop-in replacement for pairs:
local letters = {A="hi", B= "my", C ="name", D="is"}
for name, value in orderedPairs(letters) do
print(name,value)
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With