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

Комментарии 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 может потребоваться на практике?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации