CSV 文件到 Lua 表并作为新表或函数访问这些行()

Posted

技术标签:

【中文标题】CSV 文件到 Lua 表并作为新表或函数访问这些行()【英文标题】:Csv file to a Lua table and access the lines as new table or function() 【发布时间】:2019-10-28 10:38:27 【问题描述】:

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

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 文件中逐行声明新表,其行为与我的旧简单表完全相同。不知道这是否可行。

使用 Lua 5.1

【问题讨论】:

【参考方案1】:

您可以将 csv 文件作为字符串读取。我将在这里使用多行字符串来表示 csv。

gmatch 与模式 [^\n]+ 将返回 csv 的每一行。 gmatch[^,]+ 模式将返回给定行中每一列的值。

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

唯一不能移动的列是Name 列的第一列,如果移动它,它将更改用于将行存储到表中的键。

使用gmatch[^,]+[^\n]+ 2 个模式,您可以将字符串分隔到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

以下是使用 I/O 库加载 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) 替代 for 循环部分中的 csv:gmatch("[^\n]+") 。

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

-- 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,
    ,

【讨论】:

非常感谢您的教育和信息丰富的回答。它真的帮助我理解了发生了什么,我现在在我的代码中实现了这个概念。很高兴。 如果这完全回答了您的问题,您可以通过单击投票按钮下方的灰色勾号将其标记为已回答:)

以上是关于CSV 文件到 Lua 表并作为新表或函数访问这些行()的主要内容,如果未能解决你的问题,请参考以下文章

将 CSV 导入新表 -MS Access

使用 SELECT INTO 创建一个新表并添加一个主键

将 plsql 函数的值复制到新表中

text 新表或列

Lua - 反射 - 获取对象上的函数/字段列表?

数据库:订单属性的新表或新字段