从任意深度哈希中优雅地提取所有字符串

时间:2012-12-29 16:31:22

标签: ruby-on-rails ruby hash

我的目标是确定散列中是否有空白:

{"departure_time_slots"=>{"date"=>[""], "time"=>{"start"=>[""], "end"=>[""]}}}

字符串是嵌套的任意时间。我不想手动检查每一个。如果我可以提取所有字符串而不管它们的深度如何,那将是很好的。有没有一种简单的方法可以做到这一点?

3 个答案:

答案 0 :(得分:5)

以下是如何提取值的示例。但是,您仍然会遇到将值与键匹配的问题。你不可能同时拥有两者。

# Extend the Hash class
class Hash
  def recursive_values
    self.values.collect { |v|
      v.is_a?(Hash) ? v.recursive_values : v
    }.flatten
  end
end

用法:

h = {"departure_time_slots"=>{"date"=>[""], "time"=>{"start"=>[""], "end"=>[""]}}}
h.recursive_values
=> ["", "", ""]

答案 1 :(得分:0)

不可能。因为它们完全存在于彼此不同的范围内。 例如,密钥startend完全未知,并且在上面的示例中屏蔽了departure_time_slots对象。

一种圆形邻接方式可以是,再次获取hashmap的所有值,这些值都是hashmap类型,并且可以重复获取它们的键。

获取departure_time_slots的键,然后从该映射的值列表中查找每个值的所有键,如果它是一个hashmap。除此之外,我认为还有另一种方式。

P.S。在旁注中,看看你是否可以将你的结构修改为一个数组,其中元素也可以是数组,并尝试使用flatten概念的数组。 :P

答案 2 :(得分:0)

如果您使用这样的话会更好:

departure_time_slots = {:date => Time.new, :time_start => nil, :time_end => nil}

当你在Hash中使用键时,最好使用Symbols作为键。 (http://www.ruby-doc.org/core-1.9.3/Symbol.html)