3

我有一个哈希,它有一个未知的集合和嵌套数组、哈希、哈希数组和字符串的混合。这是 的结果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
4

2 回答 2

3

无需拆分字符串处理,您可以在一个递归例程中完成所有操作,如果您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
于 2013-11-13T08:33:28.913 回答
2

尽管我没有研究递归,但我必须评论您正在编写的 if 语句在 case 语句中更容易阅读:

def clean_node(node)
  case node
    when String then clean(node)
    when Array
      node.each_with_index do |obj, i|
        case obj
          when String
            node[i] = clean(node[i], obj)
          else
            clean_node(obj)
        end
      end
    when Hash....
于 2013-11-13T08:15:58.093 回答