我有一个哈希,它有一个未知的集合,混合了嵌套数组,哈希,哈希和字符串数组。这是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
答案 0 :(得分:2)
虽然我没有研究过递归,但我必须评论一下这样一个事实,即你正在编写if语句中更容易阅读的语句:
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....
答案 1 :(得分:2)
如果在例程结束时返回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