Ruby对比对应name的fx值触发TypeError,求解决思路
问题分析与修正方案
错误原因拆解
- 数组迭代错误:
b.each do |k,v|遍历的是数组b而非单个哈希行,数组的each传两个参数会返回索引+元素,而非哈希的键值对,这直接触发了String转Integer的类型错误。 - 变量笔误:代码中
e_row是未定义变量,实际应为b_row。 - 哈希值访问错误:Ruby哈希取值无需
.value方法,a_row['name']直接返回对应值,多余的.value会导致调用nil的方法报错。 - 逻辑错误:
a_row['fx'].value.to_f != a_row['fx'].value.to_f是自我比较,永远为false,且未与b_row的fx值对比。 - 未过滤无效元素:数组首元素只有
src键,无name和fx,遍历会导致a_row['name']为nil,触发后续报错。
修正后的代码
以下代码实现了按name匹配对比fx值,并返回差异结果(支持四舍五入):
def compare_values a = [{"src"=>"reportStack"}, {"name"=>"XPT", "fx"=>"1.1315313597682419"}, {"name"=>"XAU", "fx"=>"27.0165670831070071"}, {"name"=>"XAG", "fx"=>"8.4192241535397429"}] b = [{"src"=>"reportOverflow"}, {"name"=>"XPT", "fx"=>"1.13163"}, {"name"=>"XAU", "fx"=>"27.0165670831070071"}, {"name"=>"XAG", "fx"=>"8.4192"}] # 过滤掉无name的无效元素,转成以name为键的哈希(存浮点值) a_map = a.select { |h| h.key?('name') }.to_h { |h| [h['name'], h['fx'].to_f] } b_map = b.select { |h| h.key?('name') }.to_h { |h| [h['name'], h['fx'].to_f] } # 找出a中与b fx值不同的条目,支持四舍五入(示例保留5位小数) diffs = a.select do |h| next unless h.key?('name') name = h['name'] a_fx = a_map[name] b_fx = b_map[name] a_fx != b_fx end.map do |h| # 可选:四舍五入处理fx值 rounded_fx = sprintf("%.5f", h['fx'].to_f) { "name" => h['name'], "fx" => rounded_fx } end # 如果只需要单个差异结果(如第一个),可以取diffs.first diffs.first end # 调用示例 p compare_values # 输出:{"name"=>"XPT", "fx"=>"1.13153"}(四舍五入后)或原fx值
关键优化点
- 高效查找:将数组转成
name=>fx浮点值的哈希,对比时无需嵌套循环,时间复杂度从O(n²)降至O(n)。 - 错误规避:提前过滤无
name的元素,避免nil值调用方法的报错。 - 灵活处理:可通过
sprintf或round方法实现fx值的四舍五入,满足不同精度需求。
内容的提问来源于stack exchange,提问作者Kamilo
相关产品推荐
相关产品推荐

