質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

1263閲覧

ネストがあるhashの、keyとvalueの取得について

ricy

総合スコア48

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2017/07/23 07:27

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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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

otn

総合スコア84538

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ricy

2017/07/24 01:27

ご回答ありがとうございました、いただいた内容を参考に実施してみたところ、 実現したい処理を実装することができました。ご回答いただいたお二方とも実装は実現できましたが、 実際に実装させていただいたコードはotnさまでしたのベストアンサーにさせていただきました。
guest

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ricy

2017/07/24 01:28

ご回答ありがとうございました、いただいた内容を参考に実施してみたところ、 実現したい処理を実装することができました。ご回答いただいたお二方とも実装は実現できましたが、 実際に実装させていただいたコードはotnさまでしたのベストアンサーにさせていただきました。 classの書き方等、非常に勉強になりました、丁寧に書いていただきありがとうございました。
退会済みユーザー

退会済みユーザー

2017/07/24 02:36

どういたしまして。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問