从ruby hash获取所有键,其中value是带有哈希值的数组

时间:2015-02-17 13:52:56

标签: ruby arrays hash

如果我有一个Hash,例如子主题,它们嵌套在Hash的值数组中:

{"school" => "School name", "teachers" => [{"name" => "Schmith", "age" => 34},{"name" => "McRight", "age" => 51}]}


def get_keys(hash)
    (hash.keys + hash.values.grep(Hash){|sub_hash| get_keys(sub_hash)}).flatten
end

使用上一个函数,我只能获得["school","teachers"],但我还需要哈希的键,它们位于“teachers”值的数组中:["school","teachers","name","age","name","age"]

我希望消除结果中的重复项:["school","teachers","name","age"]

2 个答案:

答案 0 :(得分:2)

您可以使用Enumerable#each_with_object执行类似的操作,当值为Array时,为数组中的每个对象递归调用相同的函数。

hash = {"school" => "School name", "teachers" => [{"name" => "Schmith", "age" => 34},{"name" => "McRight", "age" => 51}]}

def get_keys(hash)
  hash.each_with_object([]) do |(k, v), arr|
    arr << k
    if v.is_a? Array
      arr << v.map { |hash2| get_keys(hash2) }.uniq
    end
  end
end

puts get_keys(hash)
=> ["school", "teachers", "name", "age"]

答案 1 :(得分:2)

def get_keys(object)
  if object.is_a? Hash
    (object.keys + get_keys(object.values)).flatten.uniq
  elsif object.is_a? Array 
    object.collect{|value| get_keys value}
  else
    []
  end
end

我认为这很清楚,你可以随心所欲地筑巢。 如果对象不是数组或散列,则没有键。 如果它是一个数组,它将查找可能在所有元素中的键 如果它是一个哈希值,它将返回其键,以及可能在哈希值上的哈希键。然后,您应用flatten删除可能的空数组,并uniq删除重复值。

使用数组,它将获得可能位于

内的键