CSV-файл в таблицу Lua и доступ к строкам в виде новой таблицы или функции () - PullRequest
2 голосов
/ 13 июня 2019

В настоящее время мой код имеет простые таблицы, содержащие данные, необходимые для каждого объекта, например:

infantry = {class = "army", type = "human", power = 2} 

cavalry = {class = "panzer", type = "motorized", power = 12} 

battleship = {class = "navy", type = "motorized", power = 256}

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

Теперь я хочу сохранить эти данные в электронной таблице (CSV-файл), которая выглядит примерно так:

Name    class  type     power 

Infantry   army   human        2 

Cavalry    panzer motorized   12 

Battleship navy   motorized  256  

В электронной таблице будет не более 50 строк, и я хочу иметь возможность увеличивать столбцы в будущем.

Попробовал пару подходов из аналогичной ситуации, которую я обнаружил здесь, но из-за недостатка навыков мне не удалось получить доступ к каким-либо значениям из вложенной таблицы. Я думаю, это потому, что я не до конца понимаю, какова структура таблиц после чтения каждой строки из файла csv в таблицу, и поэтому вообще не могу печатать какие-либо значения.

Если есть способ получить name,class,type,power из таблицы и использовать эту строку точно так же, как мои старые простые таблицы, я был бы признателен за предоставление учебного примера. Другой подход может заключаться в объявлении новых таблиц из CSV, которые ведут себя точно так же, как мои старые простые таблицы, построчно из файла CSV. Я не знаю, выполнимо ли это.

Использование Lua 5.1

1 Ответ

1 голос
/ 14 июня 2019

Вы можете прочитать CSV-файл в виде строки. Я буду использовать многострочную строку здесь для представления CSV.

gmatch с шаблоном [^\n]+ вернет каждую строку CSV. gmatch с шаблоном [^,]+ вернет значение каждого столбца из данной строки.

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

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

Используя gmatch и 2 шаблона, [^,]+ и [^\n]+, вы можете разделить строку на каждую строку и столбец csv. Комментарии в следующем коде:

local csv = [[
Name,class,type,power
Infantry,army,human,2
Cavalry,panzer,motorized,12
Battleship,navy,motorized,256
]]

local items = {}                      -- Store our values here
local headers = {}                    -- 
local first = true
for line in csv:gmatch("[^\n]+") do
  if first then                       -- this is to handle the first line and capture our headers.
    local count = 1
    for header in line:gmatch("[^,]+") do 
      headers[count] = header
      count = count + 1
    end
    first = false                     -- set first to false to switch off the header block
  else
    local name
    local i = 2                       -- We start at 2 because we wont be increment for the header
    for field in line:gmatch("[^,]+") do
      name = name or field            -- check if we know the name of our row
      if items[name] then             -- if the name is already in the items table then this is a field
        items[name][headers[i]] = field -- assign our value at the header in the table with the given name.
        i = i + 1
      else                            -- if the name is not in the table we create a new index for it
        items[name] = {}
      end
    end
  end
end

Вот как вы можете загрузить CSV, используя библиотеку ввода-вывода:

-- Example of how to load the csv. 
path = "some\\path\\to\\file.csv"
local f = assert(io.open(path))
local csv = f:read("*all")
f:close()

В качестве альтернативы вы можете использовать io.lines (path), который бы занял место csv: gmatch ("[^ \ n] +") в секциях цикла for.

Вот пример использования получившейся таблицы:

-- print table out
print("items = {")
for name, item in pairs(items) do
  print("    " .. name .. " = { ")
  for field, value in pairs(item) do
    print("        " .. field .. " = ".. value .. ",")
  end
  print("    },")
end
print("}")

Выход:

items = {
    Infantry = { 
        type = human,
        class = army,
        power = 2,
    },
    Battleship = { 
        type = motorized,
        class = navy,
        power = 256,
    },
    Cavalry = { 
        type = motorized,
        class = panzer,
        power = 12,
    },
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...