2016-10-06 2 views
0

多くのレベルのサブアイテムを含むハッシュを1つのレベルのみをハッシュに変換したいと考えています。 例:多くのサブレベルアイテムを含むハッシュを非サブアイテムに変換する方法

Input: 
{"a1"=>{"a11"=>11, "a12"=>12, "a13"=>13, "a14" => {"a141" => 141} }} 

Output: 
{"a[a11]" => 11, "a[a12]" => 12, "a[a13]" => 13, "a[a14][a141]" => 141} 

上記の問題を解決するには?

+1

を私の推測では、あなたは、あなたがいけないのチェックボックスで何かをやろうとしているということです。最初の問題は何ですか? – ndn

+0

あなたの質問は不明です。 「働かない」とはどういう意味ですか?エラーメッセージが表示されますか?はいの場合、それは何を言いますか?それはどんな線を指していますか?出力はありますか?はいの場合、どの出力を得ますか?あなたはどんなアウトプットを期待していますか?なぜですか?そして、これは[tag:ruby-on-rails]と何が関係していますか? –

+1

@JörgWMittag、公正であるように、私はあなたが*「能動的なサポート依存ソリューションを受け入れる」*という意味なら、[tag:ruby-on-rails]としてタグ付けすることが適切だと思います。 – ndn

答えて

0

ハッシュキーはどのオブジェクトでもかまいません。私は、最初の配列として新しいキーを作成し、この後に戻って文字列に変換します:

def convert_keys(in_hash ={}) 
    in_hash.each_with_object({}) do |(key, value), result| 
    if value.is_a?(Hash) 
     convert_keys(value).each_pair do |converted_key, converted_value| 
     new_key = [ key ] + converted_key 
     result[new_key] = converted_value 
     end 
    else 
     result[ [key] ] = value 
    end 
    end 
end 

def parse_params(in_hash ={}) 
    convert_keys(in_hash).each_with_object({}) do |(key, value), result| 
    key_postfix = key[1..-1].map { |key_part| "[#{key_part}]" }.join 
    str_key = "#{key[0]}#{key_postfix}" 

    result[str_key] = value 
    end 
end 
0

はそれを取る:

a = {"a1"=>{"a11"=>11, "a12"=>12, "a13"=>13, "a14" => {"a141" => 141} }} 

def modi(hash) 
    hash.map do |key, value| 
    if value.is_a?(Hash) 
     value = modi(value).flatten(1) 
     ["[#{key}]" + value.first, value.last] 
    else 
     ["[#{key}]", value] 
    end 
    end 
end 

def pars(main_hash) 
    main_hash.map do |key, value| 
    modi(value).each_with_object({}) do |v, res| 
     res[v.first.prepend(key.first)] = v.last 
    end 
    end.first #* 
end 

pars(a) 
> {"a[a11]"=>11, "a[a12]"=>12, "a[a13]"=>13, "a[a14][a141]"=>141} 

*を。またはあなたがfirstメソッドを削除することができますし、それは返す:

[{"a[a11]"=>11, "a[a12]"=>12, "a[a13]"=>13, "a[a14][a141]"=>141}] 

これはあなたを助けることができ、将来的にあなたには、いくつかの新しい機能を追加します場合は、例えば、入力は次のようになります。 `

a = {"a1"=>{"a11"=>11, "a12"=>12, "a13"=>13, "a14"=>{"a141"=>141}}, "b1"=>{"b11"=>11}} 

その後、 、このメソッドの戻り値firstなし:

[{"a[a11]"=>11, "a[a12]"=>12, "a[a13]"=>13, "a[a14][a141]"=>141,{"b[b11]"=>11}] 
0

上記のご入力を考えると、ご希望の出力は

0123だった、場合
{"a1[a11]" => 11, "a1[a12]" => 12, "a1[a13]" => 13, "a1[a14][a141]" => 141} 

この方法は動作するはずです:

def convert_hash(hash, depth = 0, keys = [], memo = {}) 
    hash.each do |key, value| 
    keys = keys.first(depth) << key 
    if value.is_a? Hash 
     convert_hash(value, depth + 1, keys, memo) 
    else 
     head, *tail = keys 
     # if there was no typo in your question, then use `head.first` here 
     converted_key = tail.reduce(head) { |memo, key| "#{memo}[#{key}]"} 
     memo[converted_key] = value 
    end 
    end 
    memo 
end 

(pry)> convert_hash({"a1"=>{"a11"=>11, "a12"=>12, "a13"=>13, "a14"=>{"a141"=>141}}}) 
=> {"a1[a11]"=>11, "a1[a12]"=>12, "a1[a13]"=>13, "a1[a14][a141]"=>141} 
関連する問題