首页 > 解决方案 > 从 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(file, numIndexColumns)

用户指定索引列的数量。

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

local constructTable = function(filename, numIndexColumns)

   local tbl = csv_to_indexed(filename)
   local ret_tbl = {}

   assert(tbl[1] ~= nil)

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

   assert(numIndexColumns < #column_names,
      "Not enough total columns for the specified number of index columns",
      "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。我想我需要某种递归函数来做到这一点。但我似乎无法在我的脑海中到达那里。

标签: lua

解决方案


我有这段代码可以从 csv 文件中读取。我在我的gideros 工作室项目中使用它。它是用lua编码的。这应该开箱即用。

function loadCSV(file)

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

        while #line > 0 do
            w, l2 = line:match("\"([^\"]*)\"[,\r\n]?(.*)") -- Check for quoted string
            if not w then w, line = line:match("([^,]*)[,\r\n]?(.*)") -- Non quoted 
            else line = l2 end
            if not w then break end --Nothing or issue, break

            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 -- Assume first line is headers
            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 文件传递​​给它,然后可以随心所欲地操作数据。您还可以将数据解析为表格等等...

希望这有帮助。和平。


推荐阅读