CSV文件到Lua表并作为新表或function()访​​问行

时间:2019-06-13 19:14:14

标签: arrays lua

当前,我的代码具有简单的表,其中包含每个对象所需的数据,如下所示:

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 个答案:

答案 0 :(得分:1)

您可以以字符串形式读取csv文件。我将在此处使用多行字符串来表示csv。

格式为gmatch

[^\n]+将返回csv的每一行。 模式为gmatch的{​​{1}}将返回给定行中每一列的值。

如果添加了更多的行或列,或者如果四处移动列,只要第一行具有标题信息,我们仍将可靠地转换信息。

唯一不能移动的列是[^,]+列的第一列,如果该列被移动,它将更改用于将行存储到表中的键。

使用Name和2个模式gmatch[^,]+,您可以将字符串分成csv的每一行和每一列。以下代码中的注释:

[^\n]+

以下是使用I / O库加载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

或者,您也可以使用io.lines(path)代替for循环部分中的csv:gmatch(“ [^ \ n] +”)。

以下是使用结果表的示例:

-- 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()

输出:

-- 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("}")