如何将深度哈希转换为键数组

时间:2012-09-19 18:54:27

标签: ruby

我想以编程方式转换它:

{
"a"=>
  {"1"=>
    {"A"=>
      {"Standard"=>"true"}
    }
  },
"b"=>
  {"1"=>
    {"A"=>
      {"Standard"=>"true"}
    }
  }
}

到这样的数组:

['a/1/A/Standard', 'b/1/A/Standard']

3 个答案:

答案 0 :(得分:4)

def extract_keys(hash)
  return [] unless hash.is_a?(Hash)
  hash.each_pair.map {|key, value| [key, extract_keys(value)].join('/') }
end
extract_keys(hash)
=> ["a/1/A/Standard", "b/1/A/Standard"]

答案 1 :(得分:2)

从我的另一个answers - 适应您的情况。请参阅链接以获取更详细的flat_hash

解决方案
def flat_hash(hash, k = "")
  return {k => hash} unless hash.is_a?(Hash)
  hash.inject({}){ |h, v| h.merge! flat_hash(v[-1], k + '/' + v[0]) }
end

example = {...} # your example hash
foo = flat_hash(example).keys
=> ["/a/1/A/Standard", "/b/1/A/Standard"] 

答案 2 :(得分:1)

找到这个flatten lambda定义。

h = {
"a"=>
  {"1"=>
    {"A"=>
      {"Standard"=>"true"}
     }
  },
"b"=>
  {"1"=>
     {"A"=>
       {"Standard"=>"true"}
     }
  }
}

a = []

flatten =
  lambda {|r|
    (recurse = lambda {|v|
      if v.is_a?(Hash)
        v.to_a.map{|v| recurse.call(v)}.flatten
      elsif v.is_a?(Array)
        v.flatten.map{|v| recurse.call(v)}
      else
        v.to_s
      end
    }).call(r)
  }

h.each do |k,v|
  a << k + "/" + flatten.call(v).join("/")
end

输出:

 ["a/1/A/Standard/true", "b/1/A/Standard/true"]