rubyのhashの処理の良い書き方について相談させていただきたいです。
例として以下のようなネストしたhashについて、
ネスト箇所のtest_key2はスキップして、key-valueがあるもののみ出力させたいです。
hash = {"test_key1"=>"test_value1", "test_key2"=>[{"test_key3"=>"test_value3"}, {"test_key4"=>"test_value4"}]}
test_key2のvalueをみて処理分岐させてもいいのですが、
rubyのなにかよいメソッドをつかって上手に書けないでしょうか。
hash.each do |k,v| puts k,v end
以下のように、出力させたいです。
test_key1 test_value1 test_key3 test_value3 test_key4 test_value4
なお、ネストは2層でなく、複数層になっても対応させたいです。
以上、助言ありましたらおねがいいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
1メソッドで再帰的になんとかしてくれるメソッドは無さそうです。自分で場合分けするしか無い。
Ruby
1hash = {"test_key1"=>"test_value1", 2 "test_key2"=>[{"test_key3"=>"test_value3"}, 3 {"test_key4"=>"test_value4"}]} 4 5def foo(h) 6 h.map do |k,v| 7 if v.is_a? Array 8 v.map do |x| 9 foo(x) 10 end 11 else 12 [k,v] 13 end 14 end.flatten 15end 16 17result = foo(hash) 18 19p Hash[*result] 20 21puts result
投稿2017/07/23 09:29
総合スコア84538
0
Ruby
1# encoding: utf-8 2 3hash = { 4 "test_key1"=>"test_value1", 5 "test_key2"=>{ 6 "test_key3"=>"test_value3", 7 "test_key4"=>{ 8 "test_key5"=>"test_value5", 9 "test_key6"=>[0, 1, 2, 3], 10 "test_key7"=>{ 11 "test_key8"=>"test_value8", 12 "test_key9"=>"test_value9", 13 "test_key10"=>"test_value10", 14 "test_key11"=>{ 15 "test_key12"=>"test_value12", 16 "test_key13"=>{ 17 "test_key14"=>"test_value14", 18 "test_key15"=>{ 19 "test_key16"=>["Hello,World"], 20 "test_key17"=>"END" 21 } 22 } 23 } 24 } 25 } 26 } 27 } 28 29def test(a, b) 30 if b.is_a?(Hash) 31 b.each do |k, v| 32 test(k, v) 33 end 34 else 35 p a, b 36 end 37end 38 39hash.each do |k, v| 40 test(k, v) 41end
出力結果例
Ruby
1"test_key1" 2"test_value1" 3"test_key3" 4"test_value3" 5"test_key5" 6"test_value5" 7"test_key6" 8[0, 1, 2, 3] 9"test_key8" 10"test_value8" 11"test_key9" 12"test_value9" 13"test_key10" 14"test_value10" 15"test_key12" 16"test_value12" 17"test_key14" 18"test_value14" 19"test_key16" 20["Hello,World"] 21"test_key17" 22"END"
test_key4にtest_key5とtest_key6を追加して作ってみました。
このプログラムが正確に動くかどうかは分かりません。
#追記
配列の中にHashを入れたものに対応したバージョン。
hashはotn様のものを使わせていただきました。
Ruby
1hash = {"test_key1"=>"test_value1", 2 "test_key2"=>[ 3 {"test_key3"=>"test_value3"}, 4 {"test_key4"=>"test_value4", 5 "test_key5"=>[ 6 {"test_key6"=>"test_value6"}, 7 {"test_key7"=>"test_value7"} 8 ] 9 } 10 ] 11 } 12 13class Hash 14 def h_flat 15 F2H.flat_hash(self) 16 end 17end 18 19class F2H 20 @result = [] 21 22 def self.process(a, b) 23 if b.is_a?(Hash) 24 b.each do |k, v| 25 self.process(k, v) 26 end 27 elsif b.is_a?(Array) 28 b.each do |e| 29 if e.is_a?(Hash) 30 @result.concat(self.flat_hash(e)) 31 else 32 @result << [a, b] 33 end 34 end 35 else 36 @result << [a, b] 37 end 38 end 39 40 def self.flat_hash(input) 41 input.each do |k, v| 42 self.process(k, v) 43 end 44 @result.uniq # 同名のキーと値があるとuniqされるので注意。 45 end 46end 47 48puts hash.h_flat 49
test_key1 test_value1 test_key3 test_value3 test_key4 test_value4 test_key6 test_value6 test_key7 test_value7
投稿2017/07/23 08:41
編集2017/07/23 10:58退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/07/24 02:36
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/07/24 01:27