Как вставить данные и таблицы в существующий?

#lua #lua-table

#lua #lua-таблица

Вопрос:

У меня возникли проблемы с вставкой новых строк и таблиц в уже существующий.

Давайте вызовем исходный файл SourceFile.lua и его упрощенное содержимое:

 SourceFile = {};

SourceFile.list = {
    BrandName1 = {
        number = 10,
        products = {
            "Product1", 3,
            "Product2", 4,
            "Product3", 7,
        },
    },
    BrandName2 = {
        number = 5,
        products = {
            "Product1", 10,
            "Product2", 3,
            "Product3", 6,
        },
    },
    -- and so on
}
  

Я хочу сделать что-то вроде этого:

 require 'SourceFile'

local myData = {
  BrandName2 = { -- add new products for the existing brand
    products = {
      "Product4", 2,
    },
  },
  MyBrandName1 = { -- add new brand
    number = 12,
    products = {
      "MyProduct1", 21,
      "MyProduct2", 95,
    },
  },
  -- and so on
}

table.insert(SourceFile.list, myData)
  

Однако в моем коде что-то не так, и я получаю следующий результат (печатается с помощью inspect ):

 {
  list = { {
      BrandName2 = {
        products = { "Product4", 2 }
      },
      MyBrandName1 = {
        number = 12,
        products = { "MyProduct1", 21, "MyProduct2", 95 }
      }
    },
    BrandName1 = {
      number = 10,
      products = { "Product1", 3, "Product2", 4, "Product3", 7 }
    },
    BrandName2 = {
      number = 5,
      products = { "Product1", 10, "Product2", 3, "Product3", 6 }
    }
  }
}
  

Что я делаю не так?

Я новичок в lua и уверен, что это что-то очевидное, но не для меня. Пожалуйста, помогите мне.


Добавление

После этих ответов я также нашел способ вставлять новые названия брендов одно за другим:

 SourceFile.list.MyBrandName1 = {
    number = 12,
    products = {
      "MyProduct1", 21,
      "MyProduct2", 95,
    },
}
  

Это не полностью отвечает на мой вопрос, но может быть полезно для кого-то нового в lua.

Ответ №1:

table.insert добавляет свой второй аргумент в массив (его первый аргумент). Предполагается, что у вашего SourceFile.list должны быть только строковые ключи, поэтому он не может работать как массив. Вам понадобится рекурсивная функция для объединения данных из одной таблицы в другую:

 local function meld(data, newData)
  for k, v in pairs(newData) do
    local oldValue = data[k]
    if type(oldValue) ~= 'table' or type(v) ~= 'table' then
      -- One of the values is not a table, so let's clobber the old value.
      data[k] = v
    else
      -- Both are tables.
      meld(oldValue, v)
    end
  end
end

meld(SourceFile.list, myData)
  

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

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

Ответ №2:

Вы помещаете таблицу фирменных наименований в список фирменных наименований. Что делает его списком фирменных наименований таблицей с фирменными наименованиями.

 table.insert(SourceFile.list, myData)
  

Это вставляет myData в SourceFile.list . myData это таблица с фирменными наименованиями.
SourceFile.list также есть таблица с фирменными наименованиями.
Список в списке.

У вас есть 2 варианта решения этой проблемы:

  1. Вставьте каждое фирменное наименование отдельно
  2. Создайте функцию для объединения содержимого myData в SourceFile.list

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

1. Спасибо за ответ! Не могли бы вы добавить пример для 1-го варианта, пожалуйста? Я знаю, что могу добавить продукт к существующему бренду таким образом table.insert(SourceFile.list["BrandName1"].products, "Product4") . Но как это сделать с новой таблицей?

2. Вы не можете использовать table.insert для этого. table.insert используется для последовательных массивов. Итак, только цифровые клавиши. Вам нужно использовать синтаксис прямой вставки tbl[key] = val