Как стать автором
Обновить

Комментарии 7

1. В Lua таблица не эквивалентна массиву.
Запись с ключом 777 будет храниться в хеш-части таблицы.
2. У вас, скорее всего, будут проблемы при json-кодировании/декодировании таблиц с ключами «1» и «2». А если в таблице будут два ключа: 1 и «1»?
Пункт 2 — вы правы, но есть возможность «костыль» отключить… статья не о том что так надо делать, а о том что есть особенности при преобразовании из луа в жисон и обратно а решение приводится для тех у кого есть проблема и ее надо решить. к примеру в моем проекте с сервера приходит таблица с инвентарем формата {id1=count1, id2 = count2..,idN = countN} и применение доступа ar[tostring(item.id)] — расстраивает:)
Можно просто добавить в таблицу метаметод, позволяющий получать/записывать данные с автопреобразованием ключа int->string.

Думаю поможет понимание как json модуль определяет что table это объект или массив. Не секрет что в качестве этого модуля Corona использует обертку над библиотекой dkjson, которая определяет, грубо говоря, таблицу как массив если у нее все ключи это числа больше 0. Типы в json и Lua отличаются и эта конвенция вроде работает.

Моя обёртка над nlohmann json, тоже также преобразует таблицу lua в массив если все ключи целочисленные положительные. В lua по другому никак.


local nljson=require("nljson");

local a={23,45,56,'weer'}

local jsn=nljson.decode("{}");

jsn["k"]=a;

print(type(jsn))
print(jsn)

local str=tostring(jsn)
print(type(str))
print(str);

Результат:


userdata
{"k":[23.0,45.0,56.0,"weer"]}
string
{"k":[23.0,45.0,56.0,"weer"]}

Проблема судя по всему в модуле json используемом в короне, который не хранит данные как userdata, a всегда использует таблицы lua.

json.encode ожидал этот подвох и вместо несуществующего 5 ключа вставил null и по этому все закончилось успехом

Нет, не ожидал. Результат получения размера таблицы с пропускаями является неопределенным (undefined). Он может вернуть как количество элементов до первого пропуска, так и индекс элемента с максимальным числовым индексом.

В первом примере вам просто повезло, и внутренний цикл случайно угадал что в таблице 6 элементов (хотя на самом деле 5), и прошелся по ним. А в следующем примере не повезло, и получилась лажа.
Достаточно странное решение достаточно странной задачи — зачем пытаться сохранять порядок элементов в таблице, заведомо инициируемой, как хэш-таблица, а не массив?

Если элементы нужны строго по порядку, имеет смысл их сразу размещать в массиве, если они нужны по предопределённым ключам, то сразу известно, что путь обхода pairs( tab ) меняться с каждым новым изменением / добавлением элемента.

Сама задача, имхо, сильно искусственная.
Есть ли хоть один пример, где сохранение порядка вывода слабых ключей после decode может потребоваться на практике?
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории