• ベストアンサー

Rubyでハッシュの中の値からキーを取りだしたい

ハッシュの中の値からキーを取りだしたいのですが、うまくいきません。 下記のようなソースしか思い浮かばないのですが、 何か良い手はないでしょうか。 ------- if number == ban.values d = ban.keys end

  • Ruby
  • 回答数5
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • nora1962
  • ベストアンサー率60% (431/717)
回答No.4

お使いになっているRubyのバージョンは何でしょうか。 オーム社のプログラミングRuby 1.9 ライブラリ編にも例が載っています。 h = { "a" => 100, "b" => 200, "c" => 300 } s = h.select { | k, v | v == 200 } # {"b"=>200} p s.values[0] # 200 になるはずなんですが。 http://ref.xaio.jp/ruby/classes/hash/select

cutisei
質問者

お礼

書き方を変えたら動きました。配列の配列なんですね。 ありがとうございます。

cutisei
質問者

補足

どうしても動きません。 何でs.values[0]って配列なんですか?

その他の回答 (4)

  • koko_u_u
  • ベストアンサー率18% (216/1139)
回答No.5

マニュアルを読むんですね。 http://doc.okkez.net/static/192/class/Hash.html ハッシュのメソッドを上から順に読んでいくと > key(val) -> object > index(val) -> object > 値 val に対応するキーを返します。対応する要素が存在しない時には nil を返します。 とあるじゃないですか。

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.3

key の値だけほしいなら d = Hash[ ban.to_a.select{ |x| x[1]==number ].keys でヒットするキーの配列が取得できます。

cutisei
質問者

補足

あっ、間違えました。そうです。ハッシュから取りたいんです。 ですが、Internal Server Errorになってしまいます。

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.2

いったん配列に変換してSELECTメソッドを使って絞り込んで、再度ハッシュに変換するとかでしょうか。 Hash[ ban.to_a.select{ |x| x[1]>1} ] とか

cutisei
質問者

補足

申し訳ないですが、動きません。

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.1

質問の内容がいまいち分かりかねます。 ハッシュのVALUE部分からKEYの値を逆算したいということでしょうか? もう少し、やりたい事を具体的に提示願えませんか。

cutisei
質問者

補足

その通りです。普通は逆ですよねーー。 ちょっと無理なソースコードなので、なんとかならないでしょうか。

関連するQ&A

  • Rubyでforループの中のハッシュがよく分からな

    forループの中のハッシュをeachしたいのですが、 printすると、一番最後のループのハッシュだけ表示されるようです。 全部中身を出すにはどういうソースを書けばよいのでしょうか。 ----------------------- center = 7 for i in 5..13 if center < 9 ban = { "i" => center } center += 1 else ban = { "i" => center } center = center % 9 center += 1 end end ban.each{|key, value| print(key + "=>", value) }

    • ベストアンサー
    • Ruby
  • 静的ハッシュの配列のキーに対応する値の数の多さ順で表示させたい

    ハッシュのキーに対応する値の数の多さ順で表示させたいと考え、下記の所まで試行錯誤しておりますが、どうにも思ったようにソートできずにおります。 #!/usr/bin/perl use strict; my(%a, $i, $j ,$allarray ,@keys ,@keys2 ,%hash ,%files ,$a_mumei_ref ,$key ,$value ,@value ,$x ,$files); # ハッシュの配列を静的に作る %a = ( '0' => [ qw(0) ], '1' => [ qw(1 1) ], '3' => [ qw(3 3 3) ], '7' => [ qw(7 7 7) ], '2' => [ qw(2) ], '4' => [ qw() ], '5' => [ qw() ], '6' => [ qw() ], '8' => [ qw(8 8) ], '9' => [ qw(9) ], ); @keys = sort { $hash{$b} <=> $hash{$a} || length($b) <=> length($a) || $a cmp $b } keys %a; #ハッシュのキーを数字順で表示 foreach (@keys){ print $_ ."\n"; } # 静的に作ったハッシュの配列を取り出してみる foreach $i (sort keys %a) { for ($j = 0; $j <= scalar(@{$a{$i}})-1; $j++) { print '$a{'. $i. '}['. $j. ']='. $a{$i}[$j]. ' '; } $allarray=scalar(@{$a{$i}})-1; print "No$i:kosuu:$allarray"; print "\n"; #配列の値の個数を調べその配列を作成 my($a_mumei) = $allarray; $a_mumei_ref = \$a_mumei; $files{"$i"}=($i,$a_mumei_ref); } #each関数で%filesの中身を表示 while ( ( $key , $value ) = each %files ){ print "key:$key value:$$value\n" ; } #試行錯誤 foreach $x (sort { $files{$b} <=> $files{$a} } keys %files){ print "$x => $files->{$x}\n"; } @keys2 = sort {$hash{$a} <=> $hash{$b}} keys %files; #@keys2 = sort { $hash{$b} <=> $hash{$a} || length($b) <=> length($a) || $a cmp $b } keys %files; #@keys2 = sort { $hash{$a} cmp $hash{$b} } keys %files; print "@keys2\n"; print "\n"; __END__; 私のイメージしておりますのは、ソートした結果がハッシュのキーに対応する値の数の多さ順で下記のように表示させたいのですが、 どのようにすれば可能でございますか、ご教授願えませんでしょうか key:3 value:2・・・この場合valueは配列の個数 key:7 value:2 key:8 value:1 key:1 value:1 key:9 value:0 key:2 value:0 key:0 value:0 key:6 value:-1 key:4 value:-1 key:5 value:-1

    • ベストアンサー
    • Perl
  • ハッシュのハッシュを値とキーでソートする方法

    %array = ( 'A' => {   'a' => 7,   'b' => 3,   'c' => 9,   'd' => 1, }, 'B' => {   'a' => 3,   'b' => 8,   'c' => 3, },); のようなハッシュがあったとして、値の降順、1つ目のキー昇順、2つ目のキー昇順でソートし、下のような形で出力したいのですが、どのようにすればよいのでしょうか。 A  c  9 B  b  8 A  a  7 A  b  3 B  a  3 B  c  3 A  d  1

    • ベストアンサー
    • Perl
  • Ruby ハッシュ継承クラス、作成方法について

    ハッシュを拡張し、値をキーで指定した範囲内から取得したいと思っているのですが、ハッシュと同じように作成できないのでしょうか? 試行錯誤してみたのですが、記述が分かりません・・・。 class Range_List < Hash  #  # 範囲に対応する、値を取得(速度が気になりますが・・・)  #  def [](other)   @list.each { |range, value|    return value if range === other   }   nil  end end # 角度 (0..1) に対応する、十キーのリストを作成 angle_to_direction = Range_List{  # => エラー。このような記述で呼び出したい  0.0625..0.1875 => 3,  0.1875..0.3125 => 2,  0.3125..0.4375 => 1,  0.4375..0.5625 => 4,  0.5625..0.6875 => 7,  0.6875..0.8125 => 8,  0.8125..0.9375 => 9,  0.9375..1    => 6,  0..0.0625    => 6 } # 角度対応の十キーを求める p angle_to_direction[0.1]  # => 3 どうかご回答お願いいたします。

    • ベストアンサー
    • Ruby
  • ハッシュの中身の表示

    ハッシュの中身の確認ができなくて困っています。 下記のような実行文においてです。 当然、test の戻り値は、スカラーとハッシュです。ハッシュを戻すときには参照渡し記号の\もつけています。 my ($return_code, %hash_data) = test(); 表示しようとすると、 Hash(0x5b04) のような表示にしかなりません、、 (試した表示方法は、下記4つです。) (環境は、WindowsXP上での、ActivePerl-5.10.0.1004 です。) foreach $key ( keys( %Hash ) ) { print "キー値 : $key\n"; print "値 : $Hash{$key} \n " } while ( ( $key , $value ) = each %Hash ){ print "キー値 : $key\n"; print "値 : $value \n " ; } use Data::Dump qw(dump); print dump(\%hash); #print %display_test; 宜しくお願いします。

    • ベストアンサー
    • Perl
  • Perlでハッシュや配列で重複するキーについて

    ハッシュで重複するキーが値となるので、このハッシュはabdの3つのキーしか存在しないということでしょうか? %a = ('a'=>1, 'b'=>2, 'a'=>3, 'd'=>4); また、配列の場合はabadと4つ数になるということでしょうか? @a = ('a','b','a','d'); この場合配列で、重複する値を抽出するアルゴリズムが知りたいです。

    • ベストアンサー
    • Perl
  • ハッシュのハッシュの値代入で悩んでいます

    2次元風配列$yaoya_array[$i][$j]から、ハッシュのハッシュ%yaoyaを作成しようとしています。 $yaoya_array[$i][$j]の[$j]の部分は、添え字によって、以下のようなデータを表します。また、NULLの場合もあるとします。 #--- $yaoya_array の中身 $yaoya_array[$i][0] 品物の名前 $yaoya_array[$i][1] 品物の個数 $yaoya_array[$i][2] 品物の値段 上記のデータがダブりもありで、下のように複数個存在します。 #--- $yaoya_array の中身 $yaoya_array[0][0] = 'みかん'; $yaoya_array[0][1] = 3; $yaoya_array[0][2] = ''; $yaoya_array[1][0] = 'みかん' $yaoya_array[1][1] = ''; $yaoya_array[1][2] = 300; 上記のデータから、下記のようなハッシュのハッシュ%yaoyaを作成しようとしています。要するに、ばらばらに存在する品物のデータをまとめようとしています。 %yaoya = ('みかん' => {'個数' => 3, '値段' =>300}); そこで、下記のようにしてみたのですが、forループが終わった時には、'kosuu'に何も入っていません。具体的には、1回目のループで'kosuu'=>3、'nedan'=>""になり、2回目のループで'kosuu'=>""、'nedan'=>300となってしまい、'kosuu'=>3が保存されていないみたいです。ifでNULLの場合は値を代入しないようにしているつもりなのですが…。 ループ終了時に'kosuu'=>3、'nedan'=>300となるようにするには、どうすればよいのでしょうか? #-- %yaoya の作成 for my $i( 0 .. $#yaoya_array ){ if( $yaoya_array[$i][1] ne "" ){ %yaoya = ( $yaoya_array[0] => {'kosuu' => $yaoya_array[$i][1]} ); } if( $yaoya_array[$i][2] ne "" ){ %yaoya = ( $yaoya_array[0] => {'nedan' => $yaoya_array[$i][2]} ); } }

    • ベストアンサー
    • Perl
  • ハッシュ(単語数を数える) たのしいRuby

    たのしいRuby P252に掲載されていた、例題 「ハッシュ(単語数を数える)」の解説を読んでも 意味が分からなかったので教えてください。 ■例題word_count.rb 1:# 単語数のカウント 2: 3: count = Hash.new(0) 4: 5:## 単語の集計 6:while line = gets 7: words = line.split 8: words.each{|word| 9: count[word] += 1 10: } 11:end 12: 13:## 結果の出力 14:count.sort{|a,b| 15: a[1] <=> b[1] 16:}.each{|key, value| 17: print "#{key}: #{value}\n" 18} ■疑問1. 解説には、 # 3行目で出現回数を記録するハッシュcountを作ります。 # countは、キーが単語、値がその単語が出現した回数を表します。 と書かれているのですが、「キーが単語、値がその単語が出現した回数を表します」 の内容が理解できません。newしただけなのに、どうして、 キーと値の内容が決まるのでしょうか? ■疑問2. 解説には、 # 8行目からの繰り返しでは、それぞれの単語をキーにして、countから出現回数を取り出し、 # +1します。 と書かれているのですが、「count[word] += 1」 の内容が理解できません。 作成したハッシュcountと、getsメソッドで読み込み単語単位に分割した配列wordsとが、 どこで関連付けされているのかが、分かりません。 ■疑問3. 解説には、 # ruby word_count.rb README という形で、Rubyに同梱されているREADMEファイルの単語数を調べた 実行結果が掲載されているのですが、 そのときの具体的な処理の流れが分かりません。 「ruby word_count.rb README」と書くだけで、 処理の流れが、getsの所まできたとき、 自動的に指定ファイル名を判断し、 読み込みを始めるということなのでしょうか。

    • ベストアンサー
    • Ruby
  • ハッシュで重複キーを認める方法について

    現在、Perlを用いてBootstrap法という方法論によるデータの加工を行っています。 その中でハッシュを使います。 それはkeyでsortしvalueを並び替え、その並び替えたvalueを処理することが目的です。  例えばこのようなものです。  Height  Weight   170.6  54.8   185.7  87.2   156.1  78.6   185.7  87.2   164.5  54.7   156.1  45.3    :     : 以上のようなデータに対し、Heightをkeyにsortし、Weightを並び替え、その並び替えたWeightの値を上から順に同数ずつ、複数のグループに分類することが目的です。 ですがハッシュでは重複keyはvalueが上書きされてしまうので、元のデータより少なくなってしまい正確なsort、並び替えができません。 Perlでこの重複を回避する方法を教えていただきたく思います。

    • ベストアンサー
    • Perl
  • ハッシュ法でのデータ管理について教えてください

    ハッシュ法でのデータ管理をするプログラムを作りたいんですが長いことPASCALに触ってなかったせいか全く分かりません。 どなたか教えていただけないでしょうか??問題の概要は以下のようなものです。 表に登録するデータについては、キーは英数字からなる長さ8までの文字列でデータ本体は整数(型名はintegerでよい)です。 ハッシュ表のサイズは11とします。 ハッシュ関数は文字列xの各文字のASCIIコードの総和を11で割った余りとします。 さらにメニュー表示として入力した文字により行う操作を決定します。 どの文字がどのような操作を行うのかは以下のとおりです。 's' の場合: ハッシュ表に登録されている全レコードを,ハッシュ関数値毎に(キーの値とデータの両方を)すべて表示します. 'r' の場合: さらに「キーの値」と「データ」を入力し,すでに同じキーをもつデータがあれば「二重登録」として検出し,そうでなければ,そのレコードをハッシュ表に登録します. 'e' の場合: さらに「キーの値」を入力し,そのキーをもつデータがハッシュ表に登録されているならば, そのデータを表示します.さらに削除するかどうかを入力させて,削除する選択をした場合にはそのレ コードを削除します.そのキーをもつデータがハッシュ表にない場合には「そのキーをもつレコードが ないこと」を出力しますが,ハッシュ表には操作を加えません. 'i' の場合: ハッシュ表に登録されている全レコードを,キーの値が小さい順に表示します.ここで「キー の値の順」とは,文字列の辞書順のことを意味します.Pascal では,文字列a,b に対して,a がb より 辞書的順序が先(小さい) ときには「a<b」で表現できます. 'd' の場合: 「'i' の場合」の逆で,キーの値が大きい順に表示します. 'q' の場合: プログラムを終了します.具体的には,実行文部の最後の「end.」の直前までジャンプし ます. 長くなってすいません。ちょっとしたヒントでもいいので教えていただければ幸いです。