Чтение таблицы lua с индексом слова дает случайный порядок

Ниже приведен код lua для чтения таблицы с индексами слов. чтение этого в другую таблицу и печать его на выходе дает случайный порядок каждый раз, когда он запускается.

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

ВЫВОД: каждый раз в другом порядке


person lancer025    schedule 08.04.2013    source источник


Ответы (3)


Как говорит Егор, итератор пар возвращает табличные значения в произвольном порядке. Чтобы отсортировать данные и вернуть их в упорядоченном формате, вам нужно использовать, например, ipairs

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

см. lua: перебор всех пар в таблице для получения дополнительной информации.

person Jane T    schedule 08.04.2013

Это специальная функция Lua 5.2.1 :-)
Но зачем эта функция была введена?
В любом случае, вы не должны полагаться на порядок, сгенерированный функцией pairs.


РЕДАКТИРОВАТЬ:
Эта функция была введена для борьбы с атаками коллизии хэшей на веб-серверах, использующих Lua.
Алгоритм рандомизированного хеширования не позволяет легко генерировать строки с одинаковыми хэшами.
Порядок ключей таблиц, сгенерированных функцией pairs, зависит от хэшей строк для ключей строкового типа, поэтому строковые ключи случайно перепутались при каждом запуске программы.

person Egor Skriptunoff    schedule 08.04.2013
comment
Вероятно, он был введен, чтобы явно сломать любой код, основанный на определенном порядке. Таким образом, люди, случайно написавшие такой код, получат некорректное поведение и исправят его. - person Nicol Bolas; 08.04.2013
comment
@NicolBolas, это не было причиной, но у него есть побочный эффект, и это хорошо. - person lhf; 08.04.2013

Из Lua PiL об итераторах:

Функция pairs, которая выполняет итерацию по всем элементам в таблице, аналогична, за исключением того, что функция итератора является следующей функцией, которая является примитивной функцией в Lua:

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

Вызов next(t, k), где k — ключ таблицы t, возвращает следующий ключ в таблице в произвольном порядке. (Он также возвращает значение, связанное с этим ключом, в качестве второго возвращаемого значения.) Вызов next(t, nil) возвращает первую пару. Когда пар больше нет, next возвращает nil.

И перечисление для next гласит:

next (table [, index])

Порядок перечисления индексов не указан, even for numeric indices. (Чтобы перемещаться по таблице в числовом порядке, используйте числовой for или функцию ipairs.)

person hjpotter92    schedule 08.04.2013