将嵌套哈希展平为数组

时间:2013-07-12 11:00:15

标签: ruby

我想将嵌套哈希展平为数组。例如:

a = {'1'=>{'2'=>{'5'=>{},'6'=>{'8'=>{}}}},'3'=>{},'4'=>{'7'=>{}}}

和flatten_nested_hash(a)的结果将是:

["1", "2", "5", "6", "8", "3", "4", "7"]

最后我写了一些递归函数,但我觉得必须有一些更简单,非递归的方法。

我的功能如下:

  def flatten_nested_hash(categories)
    categories.map do |k,v|
      if v == {} 
        k
      else
        [k,flatten_nested_hash(v)]
      end
    end.flatten
  end

5 个答案:

答案 0 :(得分:14)

递归。

def flatten_nested_hash(categories)
  categories.flat_map{|k, v| [k, *flatten_nested_hash(v)]}
end

在Hash类中定义它。

class Hash
  def flatten_nested; flat_map{|k, v| [k, *v.flatten_nested]} end
end

答案 1 :(得分:5)

使用Ruby 2.1及更高版本,您可以使用细化向Hash添加方法,并仅将其公开给您需要的模块/类。

module HashRefinements
  refine Hash do
    def flatten_nested
      flat_map { |k, v| [k, *v.flatten_nested] }
    end
  end
end

在你的课程/模块中

class MyThing
  using HashRefinements

  ...

  def flatten_categories
    categories.flatten_nested
  end

  ...
end

答案 2 :(得分:3)

这是一个嵌套的数据结构 - 您将不得不使用某种递归或迭代方法来提取所有键。但是,这比你拥有的要容易一些:

def deep_extract_keys(hash)
  hash.keys + hash.values.flat_map {|value| deep_extract_keys value }
end

p deep_extract_keys({"1"=>{"2"=>{"5"=>{}, "6"=>{"8"=>{}}}}, "3"=>{}, "4"=>{"7"=>{}}})

这是广度优先搜索,而不是深度优先搜索,因此输出为:

["1", "3", "4", "2", "5", "6", "8", "7"]

答案 3 :(得分:0)

这不是(显式)递归,仅适用于非负整数键:

a.to_s.scan(/\d+/).map(&:to_i)   # [1, 2, 5, 6, 8, 3, 4, 7]

: - )

答案 4 :(得分:0)

LoginActivity