从 CSV 数据构建索引的 Lua 表

我正在尝试创建一个 lua 工具来读取逗号分隔格式的电子表格。

这是逗号分隔数据的示例:

Test Mode,Mode Pass,Parameter1,Parameter2,Parameter3
1,1,M1p1p1,M1p1p2,M1p1p3
1,2,M1p2p1,M1p2p2,M1p2p3
1,3,M1p3p1,M1p3p2,M1p3p3
2,1,M2p1p1,M2p1p2,M2p1p3
2,2,M2p2p1,M2p2p2,M2p2p3

索引列和数据列的区别在于索引列创建具有来自列的索引的子表数组,而数据列将是表对象。

从上面的示例中:

myCSVFileTable.TestMode[1].ModePass[2].Parameter2 == M1p2p2
myCSVFileTable.TestMode[2].ModePass[1].Parameter3 == M2p1p3

我正在尝试创建的函数将如下所示:

constructTable(文件名,numIndexColumns)

用户指定索引列的数量。

到目前为止,我正在使用以下代码读取 CSV 数据并将其放入一个表中,按 CSV 文件行进行索引。

local constructTable = function(文件名,numIndexColumns)

   local tbl = csv_to_indexed(文件名)
   local ret_tbl = {}

   assert(tbl[1] ~= nil)

   local column_names = tbl[1]
   local ret_tbl = {}

   assert(numIndexColumns < #column_names,
      "指定的索引列数不足够整个列数",
      "constructTable")
end

所以 tbl 最终看起来像这样:

tbl sequence[6]
[1] sequence[6]
    [1] "Test Mode"
    [2] "Mode Pass"
    [3] "Parameter1"
    [4] "Parameter2"
    [5] "Parameter3"
[2] sequence[6]
    [1] "1"
    [2] "1"
    [3] "M1p1p1"
    [4] "M1p1p2"
    [5] "M1p1p3"
[3] sequence[6]
    [1] "1"
    [2] "2"
    [3] "M1p2p1"
    [4] "M1p2p2"
    [5] "M1p2p3"
[4] sequence[6]
    [1] "1"
    [2] "3"
    [3] "M1p3p1"
    [4] "M1p3p2"
    [5] "M1p3p3"
[5] sequence[6]
    [1] "2"
    [2] "1"
    [3] "M2p1p1"
    [4] "M2p1p2"
    [5] "M2p1p3"
[6] sequence[6]
    [1] "2"
    [2] "2"
    [3] "M2p2p1"
    [4] "M2p2p2"
    [5] "M2p2p3"

在这一点上,我不确定如何构建我的示例中定义的 myCSVFileTable。我认为我需要某种递归函数来实现这一点。但是我无法理解它。

点赞
用户870125
用户870125

我有一段代码来读取 csv 文件。我在我的 gideros studio 项目中使用它。这是用 Lua 编写的。这应该是开箱即用的。

function loadCSV(file)

    local function csvsplit(line)
        local t, w, l2 = {}, nil, nil

        while #line > 0 do
            w, l2 = line:match("\"([^\"]*)\"[,\r\n]?(.*)") -- 检查带有引号的字符串
            if not w then w, line = line:match("([^,]*)[,\r\n]?(.*)") -- 非引号的
            else line = l2 end
            if not w then break end -- 无内容或有问题,跳出循环

            t[#t + 1] = w
        end

        return t
    end

    local headers, csv = nil, {}

    for line in io.lines(file) do
        f = csvsplit(line)
        if not headers then -- 假设第一行是标题
            headers = {} for n, v in ipairs(f) do headers[v] = n end
        else
            csv[#csv + 1] = f
        end
    end

    csv.getField = function(self, row, field) return self[row][headers[field]] end

    return csv

end
--csv=loadCSV("135-bis-bt.csv")
--print(csv:getField(4,"Value"))
--print(csv:getField(7,"Time")

在代码的末尾,你可以找到一些用例。第一个参数是行数,第二个参数是标题名称。

这非常简单:你传入你的 csv 文件,然后可以按照自己的需求操作数据。你还可以将数据解析成表格等等...

希望这能有所帮助。 和平。

2019-07-22 19:43:14