Perlでハッシュの内容を出力するにはどうすればよいですか?


167

#割り当てられたバケット数/#としてハッシュを印刷し続けます。ハッシュの内容を印刷するにはどうすればよいですか?

whileループを使用しないことが最も望ましいでしょう(たとえば、ワンライナーが最適です)。

回答:


253

Data :: Dumperはあなたの友達です。

use Data::Dumper;
my %hash = ('abc' => 123, 'def' => [4,5,6]);
print Dumper(\%hash);

出力されます

$VAR1 = {
          'def' => [
                     4,
                     5,
                     6
                   ],
          'abc' => 123
        };

3
元のポスターにも非常に便利です「SORTKEYS」上の特定の転換で、様々なデータ:: Dumperのオプションの中に見たいと思うかもしれません
plusplus

1
@JonathanDay私はその詳細が欠けていて、役に立ちました!ありがとう!
Sos 2014

5
%の前にスラッシュを追加するとはどういう意味ですか?
シャンプー2016年

16
@shampooスラッシュ演算子は、&CおよびC ++の演算子と少し似た参照を作成します。このコンテキストで重要な理由は、Perlでハッシュ値を引数として関数を呼び出すと、そのハッシュ値がリスト化されて複数の引数に展開さ%hsh=("a" => 1, "b" => 2); foo(%hsh);れるためfoo("a", 1, "b", 2)です。これはと同等です。あなたが代わりに関数は、ハッシュ自体を操作したい場合は、ハッシュへの参照を渡す必要がありますfoo(\%hsh);参照してくださいperldoc.perl.org/perlsub.html#Pass-by-Reference
テトロミノ

63

簡単:

print "$_ $h{$_}\n" for (keys %h);

エレガントですが、実際には30%遅くなります(!):

while (my ($k,$v)=each %h){print "$k $v\n"}

9
Sleazy: "@_ \ n"を出力しますが、
@ _

私はあなたの意味だと思いprint "$_ $h{$_}\n" for (keys %h);$kその例には存在しません。
Chas。オーウェンズ

4
また、効率について主張する前のベンチマーク(または少なくとも、あなたが話している効率のタイプを認定​​する)。forループはより速いですwhile:少なくとも10,000個のキーまでgist.github.com/151792
チャス。オーエンス

1
もちろん、あなたは正しいです:$ k。しかし、Perl 6ではより効率的です!:)はい、あなたもその通りです。私は実際に自分のPerlを最適化したりプロファイリングしたりすることを考えたことはなかったでしょうが、これを学んでよかったです。もちろん、それぞれがなければならない(キー上の余分なハッシュ・ルックアップがないので)、より効率的であること。しかし、それは30%遅くなります!
Jonathan Graehl、2009

こんにちは、ジョナサン・グレール。申し訳ありませんが、まだ理解できません。あなたは何に基づいてそれぞれが〜30%遅いと言っていますか?いつでも、どのような状況でも、30%のギャップがありますか?
CarlosSá2017年


24

デバッグの目的で、私はしばしば使用しますYAML

use strict;
use warnings;

use YAML;

my %variable = ('abc' => 123, 'def' => [4,5,6]);

print "# %variable\n", Dump \%variable;

結果:

# %variable
---
abc: 123
def:
  - 4
  - 5
  - 6

その他の場合は使用しますData::Dump。の場合ほど多くの変数を設定して、適切な形式で出力する必要はありませんData::Dumper

use Data::Dump = 'dump';

print dump(\%variable), "\n";
{ abc => 123, def => [4, 5, 6] }

最近ではData::Printer、デバッグに使用しています。

use Data::Printer;
p %variable;
{
    abc   123,
    def   [
        [0] 4,
        [1] 5,
        [2] 6
    ]
}

(端末では結果がはるかにカラフルになる可能性があります)

ここで示した他の例とは異なり、この例は表示のみを目的として明示的に設計されています。tieされた変数の構造またはオブジェクトの構造をダンプすると、より簡単に表示されます。

use strict;
use warnings;

use MTie::Hash;
use Data::Printer;

my $h = tie my %h, "Tie::StdHash";
@h{'a'..'d'}='A'..'D';
p %h;
print "\n";
p $h;
{
    a   "A",
    b   "B",
    c   "C",
    d   "D"
} (tied to Tie::StdHash)

Tie::StdHash  {
    public methods (9) : CLEAR, DELETE, EXISTS, FETCH, FIRSTKEY, NEXTKEY, SCALAR, STORE, TIEHASH
    private methods (0)
    internals: {
        a   "A",
        b   "B",
        c   "C",
        d   "D"
    }
}

色があることは「きちんとしている」が、私が何か間違っているか、または「use Data :: Printer; p%var;」を使用している ハッシュで矢印を印刷しません、そして私のような初心者のために役立ちます
Sos

@Sosi回答の出力を見ると、=>期待どおりに出力されていないことがわかります。代わりに、常にキー、いくつかのスペース、そして値を出力します。これは、人間による出力のスキャンに役立ちます。
ブラッド・ギルバート

12

答えはハッシュの内容によって異なります。単純なハッシュがある場合、単純な

print map { "$_ $h{$_}\n" } keys %h;

または

print "$_ $h{$_}\n" for keys %h;

でも、参照が入力されているハッシュがある場合、それらの参照をウォークして適切な出力を生成できるものになります。参照のこのウォーキングは通常、シリアル化と呼ばれます。さまざまなスタイルを実装する多くのモジュールがあり、より一般的なものは次のとおりです。

事実によるData::DumperコアPerlライブラリの一部であり、それはおそらく最も人気があります。ただし、他のモジュールのいくつかは非常に優れた機能を備えています。


10

私のお気に入り:Smart :: Comments

use Smart::Comments;
# ...

### %hash

それでおしまい。


5
申し訳ありませんが、実際の機能のコメントをハイジャックするものについては、私から反対票を投じてください。メンテナンスプログラマーは、このようなコードが予期しないものを出力する理由を解明するために、一日中費やすことができます。
MikeKulls 2013

2
@ MikeKulls、np。これはソースフィルターなので、理解できます。また、私が本番の準備に入れたすべてのモジュールをチェックするスクリプトを記述していないuse Smart::Commentsため、その観点からもそれを確認しています。しかし、カウンターに対してSmart::Commentsは、スコープ付きモジュールとしてかなり適切に動作し、SCを使用しないモジュールでは出力動作が発生しないはずです。したがって、問題は、useステートメントを使用してこれらのスコープに分離されます。含まれているモジュールのドキュメントをメンテナンスプログラマーが読む責任がないと言っているのであれば、私は同意できません。それでも、コメントしてくれてありがとう
Axeman

7
彼らに責任がないと言っているわけではありませんが、彼らが最初に探すものではないでしょう。上記のコードがなぜ何かを出力していたのかわからないうちに、スマートコメントモジュールを見たことがない。コメントは何もしないはずなので、コメントをスキップして何日も費やして、処理することさえできませんでした。それらに何かをさせることは、非常に悪いことです。プログラムの動作を変更しない限り、ドキュメントの生成などに使用できます。
MikeKulls 2014年

4

ループ:

foreach(keys %my_hash) { print "$_ / $my_hash{$_}\n"; }

機能的

map {print "$_ / $my_hash{$_}\n"; } keys %my_hash;

しかし、純粋な優雅さのために、私はラングラングのものを選ばなければならないでしょう。私自身のコードでは、自分のforeachを選択します。またはテトロのダンパーの使用。


3
foreachとの使用法に機能的な違いはありませんmapmapforループをエミュレートするには、無効なコンテキストではなく、リスト変換に使用する必要があります
friedo

それぞれの「バイトコード」の結果を確認するのは興味深いことです... mapが多かれ少なかれ効率的かどうか疑問に思います。
Ape-in​​ago

2

私の経験では、最も簡単な方法はDumpvalueを使用することです

use Dumpvalue;
...
my %hash = { key => "value", foo => "bar" };
my $dumper = new DumpValue();
$dumper->dumpValue(\%hash);

チャームのように機能し、Perlデバッガーが行うようにハッシュを出力するため(デバッグに最適)、ハッシュのフォーマットを心配する必要はありません。さらに、DumpvalueはPerlモジュールのストックセットに含まれているので、ある種の厳しいプロキシ(私が働いているような)の背後にいる場合は、CPANをいじる必要はありません。


1

あなたが徹底的にそれを1行に保ちたい場合は(useステートメントとシバンなしで)、私はテトロミノの答えからちょっと背を向けて提案します:

print Dumper( { 'abc' => 123, 'def' => [4,5,6] } );

匿名ハッシュを使用して一時変数をスキップする以外は何もしません;)


OPは、彼には印刷が必要な「私のハッシュ」があると言っています。この答えは、自身のためにだけの賢さである
justintime

OPは1行でそれを行うことを望んでいました。それを行うための1行の方法を示しているだけでした。それで、反対票に値するのですか?
カイルウォルシュ

1

ハッシュの要素ごとに1つのスペースを追加して、よく見えるようにします。

print map {$_ . " "} %h, "\n";

1

キーを1つのライナーコードで並べ替えるのが本当に好きです。

print "$_ => $my_hash{$_}\n" for (sort keys %my_hash);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.