如何递归地从Ruby哈希生成拼接路径字符串?
修正递归函数以返回完整的哈希路径字符串
你的递归函数存在两个核心问题,导致无法返回完整的目标字符串:
- 递归调用的返回值未被收集,深层哈希的处理结果直接丢失
- 直接修改
current_path会污染后续循环的路径,导致非嵌套键的路径错误
修正后的函数
def show(hash, current_path = '') string = '' hash.each do |k, v| # 构建独立的新路径,避免修改原current_path影响后续迭代 new_path = current_path.empty? ? "#{k}" : "#{current_path}.#{k}" # 判断是否为可遍历的哈希(排除String,因为String也响应each方法) if v.respond_to?(:each) && !v.is_a?(String) # 收集递归调用的返回结果,拼接到主字符串中 string += show(v, new_path) else # 拼接键值对字符串,保留空值的输出格式 string += "#{new_path}: #{v}\n" end end string end
关键修改说明
- 路径隔离:用
new_path生成当前键的专属路径,而非直接修改current_path。原函数中处理嵌套哈希后,current_path会带上多余后缀,导致后续非嵌套键出现错误路径(比如en-us.storage_size.learn_more这类错误格式)。 - 递归结果收集:将递归调用返回的字符串拼接到主
string中,确保深层哈希的处理结果被完整保留。 - 排除字符串误判:增加
!v.is_a?(String)判断,因为Ruby的String类也实现了each方法(用于遍历字符),不排除会把字符串误判为可遍历哈希,导致逻辑错误。
使用示例
调用函数后可直接获取符合要求的完整字符串:
hash = {"en-us"=> {:learn_more=>"Learn more", :non_apple_desktop=>"To redeem, open this link.", :value_prop_safety=>"", :storage_size=> {:apple_tv_1_month_tms=> {:cta=>"Offer", :details=>"Get a 1-month subscription!.", :disclaimer=>"This offer expires on December 10, 2021.", :header=>"Watch The Morning Show ", :normal_price=>"$2.99"} } } } result = show(hash) puts result # 输出完全匹配你的目标格式
返回的result字符串可直接用于写入CSV或其他文件。
内容的提问来源于stack exchange,提问作者Dan Rubio
相关产品推荐
相关产品推荐

