编写一个接受任意大小的多维容器的函数,并将其转换为一维关联数组,其中的键是表示原始容器中值的路径的字符串。
所以{ 'one' => {'two' => 3, 'four' => [ 5,6,7]}, 'eight'=> {'nine'=> {'ten'=>11}}}
会成为
:
"{'one/two' => 3,'one/four/0' => 5, 'one/four/1' => 6, 'one/four/2' => 7, 'eight/nine/ten' : 11}"
到目前为止我已经得到了这个......但是我遇到了很多问题。对我忽略的事情的任何指示?
def oneDimHash(hash)
if hash.is_a?(Fixnum)
puts "AHHH"
else
hash.each_pair do |key,value|
if value.is_a?(Hash)
@temp_key << key << '/'
oneDimHash(value)
elsif value.is_a?(Array)
value.each_with_index do |val,index|
puts index
@temp_key << "#{index}"
oneDimHash(val)
end
else
@temp_key << key
@result["#{@temp_key}"] = "#{value}"
@temp_key = ''
end
end
end
end
答案 0 :(得分:0)
我立即怀疑你使用的是实例变量而不是方法参数/局部变量。很可能至少会产生混乱的密钥。假设无法修改方法签名,您可以通过委派辅助函数来解决对其他参数的需求。也许我会尝试这样的方法:
def oneDimHash(o)
oneDimHashInternal("", o, {})
end
def oneDimHashInternal(keyStem, o, hash)
if o.is_a? Hash
o.each_pair do |key, value|
oneDimHashInternal("#{keystem}/#{key}", value, hash)
end
elsif o.is_a? Array
# Work this out for yourself
else
# Store the (non-container) object in hash
# Work this out for yourself
end
hash
end
另请注意,Enumerable
既不是数组也不是哈希。我不知道你是否需要考虑这个问题。
答案 1 :(得分:0)
这个怎么样?
def oneDimHash(obj,parent="")
unless obj.is_a?(Hash)
puts "AHHH" # or may be better: raise "AHHH"
else
obj.flat_map do |key,value|
combined_key = [parent,key.to_s].join '/'
case value
when Hash then oneDimHash(value,combined_key).to_a
when Array then value.each_with_index.map { |v,i| [combined_key+"/#{i}",v] }
else [ [combined_key,value] ]
end
end.to_h
end
end