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

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

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

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

Q&A

解決済

2回答

2333閲覧

ruby初心者です。階層の深いhashの作り方

e38284

総合スコア12

Ruby

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

0グッド

1クリップ

投稿2016/04/08 17:56

いま、深い階層を作成しようとしています。
しかし、途中で行き詰まってしまいどうしていいかわからなくなってしましました。

ruby

1h_symptom=Hash.new 2symptom=Array.new 3cause1=Array.new 4cause2=Array.new 5 6a_line.each{|dset| 7 if dset[0]==3 then 8 h_symptom[dset[1]]=Hash.new 9 symptom=dset[1] 10 elsif dset[0]==6 then 11 h_symptom[symptom][dset[1]]=Hash.new 12 cause1=dset[1] 13 elsif dset[0]==9 then 14 h_symptom[symptom][cause1][dset[1]]=Hash.new 15 cause2=dset[1] 16 elsif dset[0]==12 then 17 h_symptom[symptom][cause1][cause2] = dset[1] 18 end 19}

dset[0]には3の倍数が入っており、さらに深い階層にも対応させたいです。

3,a 6,b 9,c 12,d 15,e 18,f 3、あ 6,い

a_lineはこんな感じになっています。
3から次の3までを階層にしたい場合、どうしたら簡略的に書くことが出来ますでしょうか?

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

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

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

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

mpyw

2016/04/08 23:05

本題とは無関係ですが symptom=Array.new cause1=Array.new cause2=Array.new これいらないです.ここで作ったインスタンスが結局 symptom=dset[1] こういった処理に全て上書きされています.
guest

回答2

0

次の機能を実装してみました。

  • ネストレベルが0番でないものが複数並ぶ場合を処理できるようにする。
  • 入力データの数字が 3 9 と飛んでいたらエラーにする。
  • ネストしたハッシュを入力データの形式で表示する。

aa.rb

ruby

1require 'awesome_print' # gem install awesome_print 2 3# 質問文にあったデータ例 4data0 = <<'EOS' 53,a 66,b 79,c 812,d 915,e 1018,f 113,126,13EOS 14 15# 追加したデータ例 16data1 = <<'EOS' 173,a 186,b 199,c 203,216,229,1 239,2 246,259,10 269,20 27EOS 28 29# 不正なデータ例 30dataX = <<'EOS' 313,a 329,c 33EOS 34 35# [nest, key] の組に配列データからネストしたハッシュを生成する 36def make_hash(lines) 37 ans = {} 38 keys = [] 39 lines.each do |line| 40 pos = line[0] / 3 - 1 41 fail "Bad data: #{line}" if pos > keys.length 42 43 keys = (pos == 0) ? [] : keys[0..(pos - 1)] 44 keys << line[1] 45 keys.inject(h = ans) do |h, key| 46 h[key] = {} unless h[key] 47 h[key] 48 end 49 end 50 ans 51end 52 53def print_keys(hash, nest = 0) 54 hash.each do |key, val| 55 puts "#{(nest + 1) * 3} #{key}" 56 print_keys(val, nest + 1) unless val.empty? 57 end 58end 59 60a_lines = data0.lines.map do |line| 61 x = line.chop.split(',') 62 [x[0].to_i, x[1..-1].join(' ')] 63end 64hash = make_hash(a_lines) 65ap hash 66p hash 67print_keys(hash) 68puts 69 70a_lines = data1.lines.map do |line| 71 x = line.chop.split(',') 72 [x[0].to_i, x[1..-1].join(' ')] 73end 74hash = make_hash(a_lines) 75ap hash 76print_keys(hash) 77puts 78 79a_lines = dataX.lines.map do |line| 80 x = line.chop.split(',') 81 [x[0].to_i, x[1..-1].join(' ')] 82end 83hash = make_hash(a_lines) 84# ap hash

実行結果

$ ruby aa.rb { "a" => { "b" => { "c" => { "d" => { "e" => { "f" => {} } } } } }, "あ" => { "い" => {} } } {"a"=>{"b"=>{"c"=>{"d"=>{"e"=>{"f"=>{}}}}}}, "あ"=>{"い"=>{}}} 3 a 6 b 9 c 12 d 15 e 18 f 3 あ 6 い { "a" => { "b" => { "c" => {} } }, "あ" => { "い" => { "1" => {}, "2" => {} }, "う" => { "10" => {}, "20" => {} } } } 3 a 6 b 9 c 3 あ 6 い 9 1 9 2 6 う 9 10 9 20 aa.rb:41:in `block in make_hash': Bad data: [9, "c"] (RuntimeError) from aa.rb:39:in `each' from aa.rb:39:in `make_hash' from aa.rb:83:in `<main>'

投稿2016/04/30 05:24

編集2017/07/23 22:16
katoy

総合スコア22324

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

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

0

ベストアンサー

こういう書き方は,**「どこまでがキーでどこからが値なのか」**が不明瞭になるので(競技プログラミングでこういう問題が用意されている場合を除き)設計ミスです.葉要素の値は空ハッシュにしてしまうほうがいいと思います.

Ruby

1entries = [ 2 [3, :a], 3 [6, :b], 4 [9, :c], 5 [12, :d], 6 [15, :e], 7 [18, :f], 8 [3, :], 9 [6, :], 10] 11 12root = {} 13entries.inject(root) do |node, entry| 14 node = root if entry[0] == 3 15 node[entry[1]] = {} if node[entry[1]].nil? 16 node[entry[1]] 17end 18 19p root 20# {:a=>{:b=>{:c=>{:d=>{:e=>{:f=>{}}}}}}, :あ=>{:い=>{}}}

投稿2016/04/08 22:26

編集2016/04/08 23:02
mpyw

総合スコア5223

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問