2

Hashドットで区切られたすべてのキー (ネストあり) のリストを取得する便利な方法は何ですか?

ハッシュがあるとします:

{ level1: { level21: { level31: 'val1', 
                       level32: 'val2' }, 
            level22: 'val3' } 
}

ハッシュ内のすべてのキー パスを表す目的の出力 (文字列の配列):

level1.level21.level31
level1.level21.level32
level1.level22

私の現在の解決策:

class HashKeysDumper
  def self.dump(hash)
    hash.map do |k, v|
      if v.is_a? Hash
        keys = dump(v)
        keys.map { |k1| [k, k1].join('.') }
      else
        k.to_s
      end
    end.flatten
  end
end

gist (仕様書付き)としても利用できます。

4

3 に答える 3

1

まあ、それはあなたがクリーナーによって何を意味するかによって異なります、しかしここにそれのより小さなバージョンがあります…

  1. サブクラスHashesまたはHash-alikesで動作します
  2. ハッシュを拡張して、コード内で見栄えを良くします。

    class Hash
      def keydump
        map{|k,v|v.keydump.map{|a|"#{k}.#{a}"} rescue k.to_s}.flatten
      end
    end
    

結果:

{ level1: { level21: { level31: 'val1', 
                       level32: 'val2' }, 
            level22: 'val3' } 
}.keydump
=> ["level1.level21.level31", "level1.level21.level32", "level1.level22"]
于 2012-12-03T00:03:01.353 に答える
0

これが私のビジョンです:

h = { 'level1' => { 'level2' => { 'level31' => 'val1', 'level32' => 'val2' } } }

class Hash
  def nested_keys
    self.inject([]) { |f, (k,v)| f += [k, v.is_a?(Hash) ? v.nested_keys : []] }.flatten
  end
end

keys = h.nested_keys

p keys
#=> ["level1", "level2", "level31", "level32"]

k1, k2 = keys.shift, keys.shift

puts [k1, k2, keys.shift].join('.')
#=> level1.level2.level31

puts [k1, k2, keys.shift].join('.')
#=> level1.level2.level32

ここに実用的なデモがあります

于 2012-12-01T20:48:34.860 に答える
0

これを可能にする追加のコードをRubyTreefrom_hash()にコミットしました:

require 'rubytree'

Tree::TreeNode.from_hash(hash).each_leaf.map{|n| "#{n.name}.#{n.parentage.map(&:name).reverse.join('.')}" }

=> ["level1.level21.level31", "level1.level21.level32", "level1.level22"]

gem require は別として、それはワンライナーです:)

于 2012-12-05T01:27:20.913 に答える