lancer025
lancer025

Reputation: 157

Reading lua table with word index gives random order

Following is a lua code to read a table with word indexes. reading this into another table and printing it in output gives random order everytime it is run.

earthquakes = {
        date8 = "1992/01/17",
        date7 = "1971/02/09",
        date6 = "2010/04/04",
        date5 = "1987/10/19"
}
sf = string.format
earthquake_num ={}

for k, v in pairs(earthquakes) do
        table.insert(earthquake_num, {key=k,value=v})
end

for i, v in pairs (earthquake_num) do
print(sf(" row %d key = %s", i, v.value))
end

OUTPUT : everytime in different order

Upvotes: 1

Views: 921

Answers (3)

hjpotter92
hjpotter92

Reputation: 80639

From Lua PiL on iterators:

The pairs function, which iterates over all elements in a table, is similar, except that the iterator function is the next function, which is a primitive function in Lua:

function pairs (t)
  return next, t, nil
end

The call next(t, k), where k is a key of the table t, returns a next key in the table, in an arbitrary order. (It returns also the value associated with that key, as a second return value.) The call next(t, nil) returns a first pair. When there are no more pairs, next returns nil.

And the enumeration for next states:

next (table [, index])

The order in which the indices are enumerated is not specified, even for numeric indices. (To traverse a table in numeric order, use a numerical for or the ipairs function.)

Upvotes: 3

Egor Skriptunoff
Egor Skriptunoff

Reputation: 23737

This is special feature of Lua 5.2.1 :-)
But what for this feature was introduced?
Anyway, you should not rely on ordering generated by pairs function.


EDIT :
This feature was introduced to fight hash collision attacks on web servers that are using Lua.
Randomized hash algorithm prevents easy generating of strings with equal hashes.
Ordering of table keys generated by pairs function depends on hashes of strings for string-type keys, so string keys are happened to be mixed up on every program run.

Upvotes: 3

Jane T
Jane T

Reputation: 2091

As Egor says the pairs iterator returns table values in an arbitrary order. To sort data and return it in a sequenced format you need to use ipairs for example

earthquakes = {
        date8 = "1992/01/17",
        date7 = "1971/02/09",
        date6 = "2010/04/04",
        date5 = "1987/10/19"
}
sf = string.format
earthquake_num ={}

for k, v in pairs(earthquakes) do
        table.insert(earthquake_num, {key=k,value=v})
end
table.sort(earthquake_num,function(a, b) return a.value < b.value end)
for i, v in ipairs (earthquake_num) do
print(sf(" row %d key = %s", i, v.value))
end

see lua: iterate through all pairs in table for more information.

Upvotes: 0

Related Questions