【问题标题】:Lua: Table Manipulation - Adding & Subtracting Key/Value Pairs Based on Another TableLua:表操作 - 基于另一个表添加和减去键/值对
【发布时间】:2015-04-19 19:27:54
【问题描述】:

我正在尝试使用收到的输入并根据找到的特定输入 (ID#) 构建一个表。此输入还包含我需要解析的变量,并且我使用其他 var 来构建完整的数据字符串。在同一个文件中,是应记录项目的列表。一旦接收到文件并由 Lua 脚本完全解析,它将以特定顺序发送回字符串,该特定顺序也位于接收到的同一文件中.

例如:

收到输入

Log Entries Received:
ID1 - 9:25AM - 10:15AM - Mike Stephens - 2/12/2015 - 111 Dynamo Dr.
ID2 - 8:07AM - 12:20PM - Gary Roberts - 1/23/2015 - 1212 Badger Way
ID3 - 11:46AM - 1:31PM - Trishia Major - 2/10/2015 - 325 March Manor
ID4 - 2:49PM - 3:13PM - Harry Davis - 12/21/2014 - 844 Anapolis Dr.
ID5 - 7:56AM - 8:47AM - Mary Hudson - 1/19/2015 - 9124 Royal Dr.
ID6 - 9:41AM - 4:16PM - Mark Harrison - 1/29/2015 - 583 Connecticut Rd.
ID7 - 10:25AM - 12:45PM - Jennifer Smith - 12/30/2014 - 42 Rodding Rd.
End of Log Entries

Order to be Sent:
ID3 - ID2 - ID5 - ID1 - ID7 - ID4 - ID6
End of Order

现在ID# 按时间顺序接收... 1、2、3、4 等;直到收到所有输入字符串。在收到的所有这些数据的末尾,是另一个应处理字符串的列表。这是一个完整的文件。

最初,我认为最好有两个单独的表,每个表都在各自独立的函数中构建和维护。第一个函数将接收队列的顺序,将表的键与接收到的顺序中的值(ID#)配对。这发生在下面称为function iD_Order(log_queue) 的函数中。第二个函数将使用输入数据构建完成的字符串,在function string_build(log_input) 中找到。我想建立第二个表,将第二个表的键设置为等于字符串中的 ID#,值等于完成的字符串本身。

我的断开连接将是如何一起使用这两个函数,以便在发送下一个队列时,它会根据接收到的队列来发送。另外,我想这样做,一旦整个队列成功通过,它就会完全删除两个表,以便该过程可以从头开始再次重复。

这是我目前根据信息得出的信息,以及我提供的最佳方法的想法。

function string_build(log_input)  -- takes input and creates strings (don't know how to build table found in this function)
    t_msg = {}
    for iD, time_In, time_Out, usr_Name, date, usr_Addr in input:gmatch("(ID%d)|(.-)|(.-)|(.-)|(.-)|(.-)") do
        finish_Str = "Operator Name: "..usr_Name.." (ID#:"..iD..") on "..date.." signed in at "..time_In.." and signed out at "..time_Out.." at "..usr_Addr.." open house location."
    end
    for k,v in pairs (t_msg) do
        t_msg.iD = finish_Str -- I strongly doubt this is correct????
    end
end

function iD_Order(log_queue) -- takes queue and puts values = order of ID#'s
    t_Queue = {}
    for iD_nmbr in log_queue:match("(ID%d)") do
        for k,v in pairs (t_Queue) do
            table.insert(t_Queue, #t_Queue, iD_nmbr)
        end
    end
end

function log(input) -- main function that receives outside input and sends it to appropriate functions
    local buffer = ""
    input = input:gsub("%s-%s", "|")
    buffer = buffer..input.."|"
    log_input = input:match("Log Entries Received:(.*)End of Log Entries")
    log_queue = input:match("Order to be Sent:(.*)End of Order")
    if log_input then
         string_build(log_input)
         buffer = buffer:sub(#log_input)
    end
    if log_queue then
         iD_Order(log_queue)
         buffer = buffer:sub(#log_queue)
    end
end

这是我不确定最佳做法的地方。总的来说,我对编程相当陌生,我正在努力学习争取的最佳实践/心态。我认为也许,让一个表在完全不同的功能中依赖另一个表可能是不好的做法?我不确定。但是我正在考虑使用另一个函数来从function iD_Order(log_queue) 中获取表格,并使用function string_build(log_input) 创建的字符串并根据iD 变量选择它们可能会很混乱,并且在最后删除表格时可能会导致问题.

如果t_Queue 的键与完成字符串中的iD 变量匹配,我认为最好将完成的字符串直接发送到t_Queue。但我很难弄清楚如何做到这一点。

  • 任何有助于了解是否可以通过一两个函数来执行此操作的帮助都很棒。
  • 我认为最好在一个函数中完成所有操作,但无法弄清楚。我可以得到一些帮助来解决这个问题吗?
  • 在构建整个表并将其发送回另一个源后,删除整个表的最佳方法是什么?这些完成的字符串被发送到已成交的订单。它可以是即时的,也可能需要几个小时。但最后,我希望在发送最终字符串后清除表格。

感谢所有帮助、意见和批评。

【问题讨论】:

    标签: lua queue key-value lua-table


    【解决方案1】:

    您的方法似乎正朝着正确的方向前进。 由于您的 IDs 是唯一的,并且它们是您要用于引用日志条目的值,因此将它们用作输入表的键是有意义的,可以作为字符串 ("ID1") 或作为数字 (@987654323 @) 但数字可能更好一些。而且由于订单表只是您的键序列,因此以任何顺序打印都变得非常容易。

    处理函数之间的依赖关系的一个好方法是为日志条目定义一个通用格式。在某个地方,您可能想要修改日志条目,按用户名排序等,因此将它们解析为表格将通过分隔字段来获得回报。

    单独的输入和输出操作

    分离输入和输出也很有帮助,您可能有多种获取日志条目的方式和多种输出方式,因此请避免耦合输入和输出。

    将范围保持在本地

    通常最好在函数中使用local 变量并返回结果,这样每次调用都不会更改全局表。如果您想解析多个文件,这可能会导致一些意外行为。当函数退出时,局部变量就消失了(除非已经返回),所以在函数reorder_log_entries() 中,创建的表在完成时都被销毁,你再次调用它,所以你不必担心删除/清空桌子。下面的代码是我将如何组织功能,但它不会读取/写入文件。

    function parse_order(log_order)
        local order = {} -- make it local to avoid clashes
        for id in log_order:gmatch("ID(%d)") do
            order[#order + 1] = tonumber(id) -- append id to table.
        end
        return order -- {3, 2, 5, 1, 7, 4, 6} in example.
    end
    
    function parse_log_entry(entry)
        local ID, time_In, time_Out, usr_Name, date, usr_Addr =
           entry:match("ID(%d) %- (.-) %- (.-) %- (.-) %- (.-) %- (.-)")
        return {id=tonumber(ID), time_in=time_In, time_out=time_Out,
            user_name=usr_Name, date=date, user_addr=usr_Addr}
    end
    
    function format_log_entry(entry)
        return "Operator Name: "..entry.user_name
           .." (ID#:"..entry.id..") on "
           ..entry.date.." signed in at "..entry.time_in
           .." and signed out at "..entry.time_out
           .." at "..entry.user_addr.." open house location."
    end
    
    input = [[Log Entries Received:
    ID1 - 9:25AM - 10:15AM - Mike Stephens - 2/12/2015 - 111 Dynamo Dr.
    ID2 - 8:07AM - 12:20PM - Gary Roberts - 1/23/2015 - 1212 Badger Way
    ID3 - 11:46AM - 1:31PM - Trishia Major - 2/10/2015 - 325 March Manor
    ID4 - 2:49PM - 3:13PM - Harry Davis - 12/21/2014 - 844 Anapolis Dr.
    ID5 - 7:56AM - 8:47AM - Mary Hudson - 1/19/2015 - 9124 Royal Dr.
    ID6 - 9:41AM - 4:16PM - Mark Harrison - 1/29/2015 - 583 Connecticut Rd.
    ID7 - 10:25AM - 12:45PM - Jennifer Smith - 12/30/2014 - 42 Rodding Rd.
    End of Log Entries
    
    Order to be Sent:
    ID3 - ID2 - ID5 - ID1 - ID7 - ID4 - ID6
    End of Order]]
    
    
    -- read the log entries from the input string
    function reorder_log_entries(input)
        local log = {}
        local log_paragraph = input:match("Log Entries Received:(.*)End of Log Entries")
        for line in log_paragraph:gmatch("%s*([^\r\n]+)") do
           entry = parse_log_entry(line)
           log[entry.id] = entry
        end
        local order = parse_order(input:match("Order to be Sent:(.*)End of Order"))
        for _, id in ipairs(order) do
           print(format_log_entry(log[id]))
        end
    end
    

    【讨论】:

    • 非常简单易懂。谢谢!我确实有一个与您的回答有关的问题。 for_,id in ipairs(order) do....,为什么有下划线的原因?你不能只输入“for k,v in ipairs (order) do....”吗?那会是一样的吗?另外,我不明白它上面的 log_paragraph:gmatch 行 5 行。使用括号/胡萝卜寻找的匹配序列到底是什么?再次感谢您!
    • @Pwrcdr87 下划线用于你不使用的变量(丢弃变量),所以for k, v 可以正常工作,但很高兴说“我不需要密钥,忘了它吧“在代码中。胡萝卜就像一个非,所以"[^\r\n]+" 匹配一个或多个非换行符。这样 for 循环将例如采用 "Hello\r\nWorld this is me\r\n" 并迭代 "Hello" 然后 "World this is me" (删除换行符)。
    • 啊哈,搞砸了。再一次非常感谢你!问题已回答并给你点数!!!希望我能给你更多。
    猜你喜欢
    • 1970-01-01
    • 2013-11-29
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 2015-01-02
    • 2020-06-26
    • 2021-04-11
    • 2019-11-07
    相关资源
    最近更新 更多