- ベストアンサー
静的ハッシュの配列のキーに対応する値の数の多さ順で表示させたい
ハッシュのキーに対応する値の数の多さ順で表示させたいと考え、下記の所まで試行錯誤しておりますが、どうにも思ったようにソートできずにおります。 #!/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
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
この程度だと無意味だけど, シュワルツ変換 @sorted_keys = map { $_->[1]; } sort { $b->[0] <=> $a->[0] or $a->[1] <=> $b->[1]; } map { [ scalar @{$a{$_}}, $_ ]; } keys %a; とか, 同系統でハッシュを 1つ余計に使って my %tmp; while (my ($key, $val) = each %a) { $tmp{$key} = @{$a{$val}}; } @sorted_keys = sort { $tmp{$b} <=> $tmp{$a} or $a <=> $b; } keys %a; でもいいかな. (無名) 配列の長さごときに使うのはやりすぎな気もするけど. $# と scalar では 1つだけ値がずれますね>#2. まあ, 一律ずれるので影響はないんですが.
その他の回答 (3)
- g_p_
- ベストアンサー率53% (28/52)
#2様、 >ところで、配列の添字数を取得するのにscalarを使用しているみたい >ですが、 @ を $# にするだけで取得できるのでは。 多分、スペースシップ演算子を使っている時点で、scalar は必要ありませんが、明示した方がわかりやすいと思ったまでです。 また、添字数を取得しているという意味ではありません。
- pick52
- ベストアンサー率35% (166/466)
ところで、配列の添字数を取得するのにscalarを使用しているみたい ですが、 @ を $# にするだけで取得できるのでは。
- g_p_
- ベストアンサー率53% (28/52)
こんにちは こんな感じですか? #! perl use strict; use Data::Dumper; my %hash = ( '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) ], ); my @sorted_keys = sort { scalar @{$hash{$b}} <=> scalar @{$hash{$a}} or $a <=> $b } keys %hash; print Dumper \@sorted_keys;
お礼
ご教授頂きありがとうございました。 Data::Dumperで表示させる事など思いもつきませんでした。 いや~素晴らしいです。 勉強になります。ありがとうございました。
お礼
これまた素晴らしいご回答をご教授頂きありがとうございます。 シュワルツ変数について調べてみたのですが、簡単そうで何だか難しいですね。 で、調べていたら「続・初めてのPerl」がヒットしたのですが、ハッと思ったんです。今、まさにちょうど図書館で借りてるじゃん! で、試しに読むと、さかのぼってソートに関してから読み始めてみると、かなり分かりやすいですね。この調子で読み進めてゆきたいと思います。 借りても読まないと意味ないですが、今回の質問がそのきっかけになって良かったです。 多謝です。ありがとうございました。