对象散列的 Ruby 递归映射

标签 ruby

我有一个散列,它包含未知的集合以及嵌套数组、散列、散列数组和字符串的混合体。这是 JSON.parse 的结果。数据的结构必须与其开始时的结构相同。最终目标是将字符串转换为可能是 Fixnums 的 Fixnums。

以下工作正常,但我想知道是否可以缩短它。请注意我如何需要 clean 方法中的键和值,因为并非所有可以是 Fixnums 的字符串都应该是。有什么想法吗?

def clean_node(node)
    if node.class == String
      clean(node)
    elsif node.class == Array
      node.each_with_index do |obj, i|
        if obj.class == String
          node[i] = clean(node[i], obj)
        else
          clean_node(obj)
        end
      end
    elsif node.class == Hash
      node.each_pair do |key, value|
        if value.class == String
          node[key] = clean(key, value)
        else
          clean_node(value)
        end
      end
    end
end

def clean(key, value)
    FIXNUM_KEYS.include?(key)? value.to_i : value
end

最佳答案

不需要拆分字符串处理,如果在例程结束时返回 node 的值,则可以在一个递归例程中完成所有操作。这具有删除一些参数的副作用,您可以就地使用 .map! 来处理数组。

使用 case 使按类型选择的内容更容易阅读。

可以通过多种方式添加处理字符串数组的能力。我选择添加一个状态变量(递归中的一种常见模式,例如计算深度)。然后在数组的情况下,递归从当前级别继承状态,而散列情况根据键列表中的查找来确定新状态(转换或不转换)以应用转换。

def clean_node( node, convert_item = false )

    case node

    when String
      node = node.to_i if convert_item

    when Array
      node.map! do |obj| 
        clean_node( obj, convert_item )
      end

    when Hash
      node.each_pair do |key, value|
        node[key] = clean_node( value, FIXNUM_KEYS.include?(key) )
      end
    end

    node
end

关于对象散列的 Ruby 递归映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19947956/

相关文章:

ruby - 在 Ruby 中赋值不需要运算符?

ruby-on-rails - active_admin jquery-gems 弄得一团糟

ruby-on-rails - 从整数中获取记录?

ruby-on-rails - 应用程序的名称是否可以作为变量使用?

ruby - 在哪里可以找到针对 Ruby 积极开发的 lint 工具?

ruby - 同时映射和选择

Ruby Hash 在 1.8.7 和 1.9.2 中的区别

ruby-on-rails - 在 respond_with 散列中包含一个虚拟属性

ruby-on-rails - 如何对一组 ActiveRecord 对象进行分组?

ruby - Ruby 大小写相等运算符失败 ===