Lua:Table 操作 - 加法和减法 Key/Value 基于另一个的对 Table
Lua: Table Manipulation - Adding & Subtracting Key/Value Pairs Based on Another Table
我正在尝试使用收到的输入并根据找到的特定输入 (ID#
) 构建 table。此输入还包含我需要解析的变量,我使用那些其他变量来构建完整的数据字符串。在同一个文件中,是一个应该记录项目的列表。一旦文件被接收并被 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 等;直到接收到所有输入字符串。在收到的所有这些数据的末尾,是应该处理字符串的另一个列表。这包含在一个完整的文件中。
最初,我认为最好有两个独立的 table,每个都在自己独立的功能中构建和维护。第一个函数将接收队列的顺序,将 table 的键与接收到的顺序中的值 (ID#'s) 配对。这发生在下面称为 function iD_Order(log_queue)
的函数中。第二个函数将使用输入数据构建完成的字符串,在 function string_build(log_input)
中找到。我想构建第二个 table,将第二个 table 的键设置为等于在字符串中找到的 ID#,并将值设置为等于完成的字符串本身。
我遇到的问题是如何同时使用这两个函数,以便在发送下一个队列时,它会根据接收到的队列进行发送。另外,我想做到这一点,一旦整个队列成功通过,它就会完全删除两个 table,这样这个过程就可以从头开始重复。
以下是我目前根据所提供的信息以及我对最佳方法的想法。
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
这是我不确定最佳做法的地方。作为一般编程的新手,我正在努力学习最好的 practice/mindset 来争取。我认为,让一个 table 在完全不同的功能中依赖另一个可能是不好的做法?我不确定。但是我正在考虑有另一个函数可以从 function iD_Order(log_queue)
中获取 table 并且使用 function string_build(log_input)
和 select 创建的字符串基于 iD
变量可能在删除最后的 table 时会很乱,可能会导致问题。
如果 t_Queue
的键与完成字符串中的 iD
变量匹配,我认为最好将完成的字符串直接发送到 t_Queue
中。但我很难弄清楚如何做到这一点。
- 任何有助于理解是否可以通过一个或两个函数来执行此操作的方法都很棒。
- 我认为最好在一个函数中完成所有操作,但无法弄清楚。我可以得到一些帮助来解决这个问题吗?
- 一旦构建了整个 table(s) 并将其发送回另一个源,删除整个 table(s) 的最佳方法是什么?这些完成的字符串被发送到已填写的订单。它可以是立即的,也可能需要几个小时。但最后,我希望在发送最终字符串后清除 table。
感谢所有的帮助、意见和批评。
您的方法似乎正朝着正确的方向前进。
由于您的 IDs
是唯一的,并且它们是您要用来引用日志条目的值,因此将它们用作输入 table 的键是有意义的,或者作为字符串("ID1"
) 或数字 (1
) 但数字可能更好一些。由于顺序 table 只是您的键的序列,因此以任何顺序打印都变得非常容易。
处理函数之间依赖关系的一个好方法是为日志条目定义通用格式。在某处您可能想要修改日志条目,按用户名排序等,因此将它们解析为 tables 将在字段分隔的情况下得到回报。
分离输入和输出操作
将输入和输出分开也很有帮助,您可能有多种获取日志条目的方法,以及多种输出日志条目的方法,因此请避免耦合输入和输出。
将作用域保持在本地
通常最好在函数中使用 local
变量并 return 结果,这样每次调用都不会更改全局 table。如果您想解析多个文件,这可能会导致一些意外行为。当函数退出时,局部变量消失了(除非已经 returned),所以在函数 reorder_log_entries()
中,创建的 table 都在它完成时被销毁,你调用 call再次使用它,这样您就不必担心 deleting/emptying 和 table 了。下面的代码是我将如何组织功能,但它不会 read/write 到文件。
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
我正在尝试使用收到的输入并根据找到的特定输入 (ID#
) 构建 table。此输入还包含我需要解析的变量,我使用那些其他变量来构建完整的数据字符串。在同一个文件中,是一个应该记录项目的列表。一旦文件被接收并被 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 等;直到接收到所有输入字符串。在收到的所有这些数据的末尾,是应该处理字符串的另一个列表。这包含在一个完整的文件中。
最初,我认为最好有两个独立的 table,每个都在自己独立的功能中构建和维护。第一个函数将接收队列的顺序,将 table 的键与接收到的顺序中的值 (ID#'s) 配对。这发生在下面称为 function iD_Order(log_queue)
的函数中。第二个函数将使用输入数据构建完成的字符串,在 function string_build(log_input)
中找到。我想构建第二个 table,将第二个 table 的键设置为等于在字符串中找到的 ID#,并将值设置为等于完成的字符串本身。
我遇到的问题是如何同时使用这两个函数,以便在发送下一个队列时,它会根据接收到的队列进行发送。另外,我想做到这一点,一旦整个队列成功通过,它就会完全删除两个 table,这样这个过程就可以从头开始重复。
以下是我目前根据所提供的信息以及我对最佳方法的想法。
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
这是我不确定最佳做法的地方。作为一般编程的新手,我正在努力学习最好的 practice/mindset 来争取。我认为,让一个 table 在完全不同的功能中依赖另一个可能是不好的做法?我不确定。但是我正在考虑有另一个函数可以从 function iD_Order(log_queue)
中获取 table 并且使用 function string_build(log_input)
和 select 创建的字符串基于 iD
变量可能在删除最后的 table 时会很乱,可能会导致问题。
如果 t_Queue
的键与完成字符串中的 iD
变量匹配,我认为最好将完成的字符串直接发送到 t_Queue
中。但我很难弄清楚如何做到这一点。
- 任何有助于理解是否可以通过一个或两个函数来执行此操作的方法都很棒。
- 我认为最好在一个函数中完成所有操作,但无法弄清楚。我可以得到一些帮助来解决这个问题吗?
- 一旦构建了整个 table(s) 并将其发送回另一个源,删除整个 table(s) 的最佳方法是什么?这些完成的字符串被发送到已填写的订单。它可以是立即的,也可能需要几个小时。但最后,我希望在发送最终字符串后清除 table。
感谢所有的帮助、意见和批评。
您的方法似乎正朝着正确的方向前进。
由于您的 IDs
是唯一的,并且它们是您要用来引用日志条目的值,因此将它们用作输入 table 的键是有意义的,或者作为字符串("ID1"
) 或数字 (1
) 但数字可能更好一些。由于顺序 table 只是您的键的序列,因此以任何顺序打印都变得非常容易。
处理函数之间依赖关系的一个好方法是为日志条目定义通用格式。在某处您可能想要修改日志条目,按用户名排序等,因此将它们解析为 tables 将在字段分隔的情况下得到回报。
分离输入和输出操作
将输入和输出分开也很有帮助,您可能有多种获取日志条目的方法,以及多种输出日志条目的方法,因此请避免耦合输入和输出。
将作用域保持在本地
通常最好在函数中使用 local
变量并 return 结果,这样每次调用都不会更改全局 table。如果您想解析多个文件,这可能会导致一些意外行为。当函数退出时,局部变量消失了(除非已经 returned),所以在函数 reorder_log_entries()
中,创建的 table 都在它完成时被销毁,你调用 call再次使用它,这样您就不必担心 deleting/emptying 和 table 了。下面的代码是我将如何组织功能,但它不会 read/write 到文件。
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