Есть ли нехакерский способ изменить значение во вложенной таблице, заданной в таблице ключей? - PullRequest
2 голосов
/ 07 января 2020

Итак, я пытаюсь изменить значение во вложенной таблице, используя таблицу ключей

Пример:

local DATA = {
    Storage = {
        Person_id = {
            Money = 0;
            Inventory = {
                Item1 = 0;
            }
        }
    }
}

local function ChangeData(ID, KeyTable, Value, Operation)
    local StorageValue = DATA.Storage[ID].Data; 
    for _, Key in ipairs(KeyTable) do
        StorageValue = StorageValue[Key];
    end

    if Operation == "+" then
        StorageValue = StorageValue + Value;
    elseif Operation == "=" then
        StorageValue = Value;
    end
end

ChangeData("person_id", {"Money"}, 5, "="};
ChangeData("person_id", {"Inventory", "Item1"}, 5, "="};

Это успешно при получении значения из вложенной таблицы ( и изменяя значение переменной), но не изменяя значение во вложенной таблице.

...

Единственный способ исправить это (который ДЕЙСТВИТЕЛЬНО НЕ ДЕЙСТВУЕТ хочу сделать) это жестко закодировать. Пример:

if Operation == "=" then
   if #KeyTable == 1 then
      DATA.Storage[ID].Data[KeyTable[1]] = Value;
   elseif #KeyTable == 2 then
      DATA.Storage[ID].Data[KeyTable[1]][KeyTable[2]] = Value;
--... and so on

Итак, что я спрашиваю: Есть ли нехакерский способ изменить значение во вложенной таблице, используя таблицу ключей?

1 Ответ

2 голосов
/ 07 января 2020

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

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

   local DATA = {
      Storage = {
          Person_id = {
              Money = 0,
              Inventory = {
                  Item1 = 5
              }
          }
      }
  }

  local function ChangeData(ID, KeyTable, Value, Operation)
      local StorageValue = DATA.Storage[ID]
      local LastKey = table.remove(KeyTable)

      for i, Key in ipairs(KeyTable) do
          StorageValue = StorageValue[Key]
      end

      if Operation == "+" then
          StorageValue[LastKey] = StorageValue[LastKey] + Value
      elseif Operation == "=" then
          StorageValue[LastKey] = Value
      end
  end

  ChangeData("Person_id", {"Money"}, 5, "=")
  ChangeData("Person_id", {"Inventory", "Item1"}, 5, "+")

  print(DATA.Storage.Person_id.Money)
  print(DATA.Storage.Person_id.Inventory.Item1)

Также, как заявлено Егором Скриптуновым в комментариях, обязательно измените next, KeyTable на ipairs(KeyTable), чтобы гарантировать сохранение порядка ключей.

...