Lua中如何向函数传入动态语句?数值条件结果异常排查
数值条件结果异常排查与动态条件传入实现
我写了一段Lua代码用于按条件拆分数据集,但数值条件的运行结果不符合预期,同时希望了解如何动态传入判断语句。
尝试代码
local data = { {cond1 = 'yes', cond2 = 'yes', nums = 7, results = 'no', average = 9.5}, {cond1 = 'yes', cond2 = 'no', nums = 12, results = 'no', average = 15}, {cond1 = 'no', cond2 = 'yes', nums = 18, results = 'yes', average = 26.5}, {cond1 = 'no', cond2 = 'yes', nums = 35, results = 'yes', average = 36.5}, {cond1 = 'yes', cond2 = 'yes', nums = 38, results = 'yes', average = 44}, {cond1 = 'yes', cond2 = 'no', nums = 50, results = 'no', average = 66}, {cond1 = 'no', cond2 = 'no', nums = 83, results = 'no'}, } function split_data(data, root_node, branch_node, root_condition_function, branch_condition_function) local true_node = {true_value = 0, false_value = 0} local false_node = {true_value = 0, false_value = 0} for _, entry in ipairs(data) do if root_condition_function(entry, root_node) then if branch_condition_function(entry, branch_node) then true_node.true_value = true_node.true_value + 1 else true_node.false_value = true_node.false_value + 1 end else if branch_condition_function(entry, branch_node) then false_node.true_value = false_node.true_value + 1 else false_node.false_value = false_node.false_value + 1 end end end return true_node, false_node end -- 字符串类型根节点条件 local function root_string_condition(entry, root_node) return entry[root_node] == 'yes' end -- 数值类型根节点条件 local function root_numeric_condition(entry, root_node, branch_node) local nums = entry[root_node] local average = entry[branch_node] -- 空值检查 if nums == nil or average == nil then return false end return tonumber(nums) < tonumber(average), tonumber(nums) >= tonumber(average) end -- 分支节点条件 local function branch_condition(entry, branch_node) return entry[branch_node] == 'yes' end -- 字符串条件示例调用 local trueNodeStr, falseNodeStr = split_data(data, 'cond1', 'results', root_string_condition, branch_condition) -- 打印字符串条件结果 print("String Condition Results:") print(string.format("Cond1 True - True Value: %d, False Value: %d", trueNodeStr.true_value, trueNodeStr.false_value)) print(string.format("Cond1 False - True Value: %d, False Value: %d", falseNodeStr.true_value, falseNodeStr.false_value)) -- 数值条件示例调用 local trueNodeNum, falseNodeNum = split_data(data, 'nums', 'results', root_numeric_condition, branch_condition) -- 打印数值条件结果 print("\nNumeric Condition Results:") print(string.format("Nums True - True Value: %d, False Value: %d", trueNodeNum.true_value, trueNodeNum.false_value)) print(string.format("Nums False - True Value: %d, False Value: %d", falseNodeNum.true_value, falseNodeNum.false_value))
实际运行结果
String Condition Results: Cond1 True - True Value: 1, False Value: 3 Cond1 False - True Value: 2, False Value: 1 Numeric Condition Results: Nums True - True Value: 0, False Value: 0 Nums False - True Value: 3, False Value: 4
预期结果
Numeric Condition Results: Nums True - True Value: 0, False Value: 1 Nums False - True Value: 3, False Value: 3
问题原因分析
- 参数传递不匹配:
split_data调用root_numeric_condition时仅传入entry和root_node两个参数,但该函数定义需要三个参数,导致average变量始终为nil,触发空值判断返回false,所有数据都进入false_node分支。 - 多返回值逻辑冗余:
root_numeric_condition返回两个布尔值,但split_data中的if语句只会取第一个返回值,第二个返回值被完全忽略。
修复方案
1. 修正参数传递与条件函数逻辑
调整split_data的参数传递逻辑,给根条件函数传入所有需要的变量;同时简化数值条件函数的返回逻辑,只返回一个布尔值表示是否满足根条件:
-- 修改split_data,给根条件函数传入branch_node function split_data(data, root_node, branch_node, root_condition_function, branch_condition_function) local true_node = {true_value = 0, false_value = 0} local false_node = {true_value = 0, false_value = 0} for _, entry in ipairs(data) do -- 传入branch_node参数 if root_condition_function(entry, root_node, branch_node) then if branch_condition_function(entry, branch_node) then true_node.true_value = true_node.true_value + 1 else true_node.false_value = true_node.false_value + 1 end else if branch_condition_function(entry, branch_node) then false_node.true_value = false_node.true_value + 1 else false_node.false_value = false_node.false_value + 1 end end end return true_node, false_node end -- 修改数值根条件函数,仅返回一个布尔值 local function root_numeric_condition(entry, root_node, average_node) local nums = entry[root_node] local average = entry[average_node] if nums == nil or average == nil then return false end return tonumber(nums) < tonumber(average) end
2. 验证修复结果
修复后运行数值条件分支,结果将与预期一致:最后一条无average的条目会进入false_node且results为no,对应false_node.false_value加1,最终得到符合预期的统计结果。
动态传入条件语句的实现
通过闭包可以灵活生成自定义条件函数,无需修改split_data的核心逻辑,示例如下:
-- 生成动态数值条件函数,支持自定义比较运算符和字段 local function create_numeric_condition(compare_field, target_field, operator) local ops = { ['<'] = function(a, b) return a < b end, ['>'] = function(a, b) return a > b end, ['<='] = function(a, b) return a <= b end, ['>='] = function(a, b) return a >= b end, ['=='] = function(a, b) return a == b end } local op_func = ops[operator] or ops['<'] return function(entry) local val = tonumber(entry[compare_field]) local target_val = tonumber(entry[target_field]) if val == nil or target_val == nil then return false end return op_func(val, target_val) end end -- 生成nums < average的条件函数 local nums_less_average = create_numeric_condition('nums', 'average', '<') -- 简化split_data,根条件函数仅接收entry参数(闭包已封装其他变量) function split_data(data, branch_node, root_condition_func, branch_condition_func) local true_node = {true_value = 0, false_value = 0} local false_node = {true_value = 0, false_value = 0} for _, entry in ipairs(data) do if root_condition_func(entry) then if branch_condition_func(entry, branch_node) then true_node.true_value = true_node.true_value + 1 else true_node.false_value = true_node.false_value + 1 end else if branch_condition_func(entry, branch_node) then false_node.true_value = false_node.true_value + 1 else false_node.false_value = false_node.false_value + 1 end end end return true_node, false_node end -- 使用动态生成的条件函数 local trueNodeNum, falseNodeNum = split_data(data, 'results', nums_less_average, branch_condition)
这种方式可以根据需求生成任意逻辑的条件函数,灵活性更高,无需改动核心拆分逻辑。
内容的提问来源于stack exchange,提问作者atlas oser
相关产品推荐
相关产品推荐

