Bagaimana saya bisa mencetak konten hash di Perl?


167

Saya terus mencetak hash saya sebagai # kotak / # yang dialokasikan. Bagaimana cara mencetak konten hash saya?

Tanpa menggunakan whileperulangan akan lebih disukai (misalnya, satu-liner akan lebih baik).

Jawaban:


253

Data :: Dumper adalah teman Anda.

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

akan menampilkan

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

3
poster asli mungkin juga ingin melihat ke berbagai Data :: opsi Dumper, khususnya menyalakan 'Sortkeys' bisa sangat berguna
plusplus

1
@ JonathanDay saya melewatkan detail itu dan itu sangat membantu! Terima kasih!
Sos

5
Apa artinya menambahkan garis miring di depan%?
keramas

16
@shampoo slash operator menciptakan referensi, sedikit mirip dengan &operator di C dan C ++. Alasan penting dalam konteks ini adalah bahwa di Perl, jika Anda memanggil fungsi dengan nilai hash sebagai argumen, nilai hash akan didaftar dan diperluas menjadi beberapa argumen - jadi %hsh=("a" => 1, "b" => 2); foo(%hsh);akan sama dengan foo("a", 1, "b", 2). Jika Anda menginginkan fungsi untuk beroperasi pada hash itu sendiri, Anda perlu memberikan referensi ke hash: foo(\%hsh);Lihat perldoc.perl.org/perlsub.html#Pass-by-Reference
tetromino

63

Mudah:

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

Elegan, tapi sebenarnya 30% lebih lambat (!):

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

9
Sleazy: print "@_ \ n" while @_ = each% h
FMc

Saya pikir maksud Anda print "$_ $h{$_}\n" for (keys %h);, $ktidak ada dalam contoh itu.
Chas. Owens

4
Juga, patok sebelum membuat klaim tentang efisiensi (atau paling tidak memenuhi syarat jenis efisiensi yang Anda bicarakan). The forloop lebih cepat daripada whilehingga setidaknya 10.000 kunci: gist.github.com/151792
Chas. Owens

1
Tentu saja Anda benar: $ k. Tetapi lebih efisien dalam Perl 6! :) Ya, Anda benar tentang itu juga. Saya tidak akan pernah berpikir untuk benar-benar mengoptimalkan atau profil Perl saya, tetapi saya senang untuk mempelajari ini. Tentu saja, masing - masing harus lebih efisien (karena tidak ada pencarian hash tambahan pada kunci). Tapi ~ 30% lebih lambat!
Jonathan Graehl

Hai, Jonathan Graehl. Maaf, masih belum mengerti. Anda mengatakan bahwa masing-masing ~ 30% lebih lambat berdasarkan apa? Apakah setiap kali, untuk setiap situasi, ada kesenjangan 30%?
Carlos Sá


24

Untuk keperluan debugging, saya akan sering menggunakan YAML.

use strict;
use warnings;

use YAML;

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

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

Hasil dalam:

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

Lain kali saya akan menggunakan Data::Dump. Anda tidak perlu mengatur sebanyak mungkin variabel untuk mengeluarkannya dalam format yang bagus daripada yang Anda lakukan Data::Dumper.

use Data::Dump = 'dump';

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

Baru-baru ini saya telah menggunakan Data::Printeruntuk debugging.

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

(Hasilnya bisa jauh lebih berwarna di terminal)

Berbeda dengan contoh-contoh lain yang telah saya perlihatkan di sini, yang ini dirancang secara eksplisit hanya untuk tujuan tampilan. Yang muncul lebih mudah jika Anda membuang struktur variabel terikat atau objek.

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"
    }
}

memiliki warna adalah "rapi", tetapi apakah saya melakukan sesuatu yang salah, atau menggunakan "menggunakan Data :: Printer; p% var;" tidak mencetak panah dalam hash, dan untuk pemula seperti saya yang membantu
Sos

@ Sosi Jika Anda melihat output dalam jawaban, Anda akan melihat bahwa itu tidak menghasilkan =>seperti yang Anda harapkan. Alih-alih itu selalu mencetak kunci, beberapa spasi, dan kemudian nilainya. Yang membantu pemindaian manusia atas output.
Brad Gilbert

12

Jawabannya tergantung pada apa yang ada di hash Anda. Jika Anda memiliki hash sederhana, sederhana

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

atau

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

akan dilakukan, tetapi jika Anda memiliki hash yang diisi dengan referensi Anda akan sesuatu yang bisa berjalan referensi tersebut dan menghasilkan output yang masuk akal. Referensi berjalan ini biasanya disebut serialisasi. Ada banyak modul yang menerapkan gaya yang berbeda, beberapa yang lebih populer adalah:

Karena fakta yang Data::Dumpermerupakan bagian dari perpustakaan inti Perl, itu mungkin yang paling populer; Namun, beberapa modul lain memiliki hal-hal yang sangat baik untuk ditawarkan.


10

Favorit saya: Cerdas :: Komentar

use Smart::Comments;
# ...

### %hash

Itu dia.


5
Maaf, beri suara untuk saya dari bawah untuk hal-hal yang membajak komentar untuk fungsi sebenarnya. Seorang programmer pemeliharaan dapat menghabiskan sepanjang hari mencoba mencari tahu mengapa kode seperti itu mencetak hal-hal yang tidak terduga.
MikeKulls

2
@MikeKulls, np. Ini filter sumber, jadi saya mengerti. Juga, setelah skrip tertulis yang memeriksa setiap modul yang saya masukkan ke persiapan produksi yang tidak use Smart::Comments, saya melihatnya dari perspektif itu juga. Tetapi bagi penghitung, Smart::Commentsberperilaku cukup baik sebagai modul cakupan , seharusnya tidak ada perilaku keluaran dalam modul apa pun yang tidak juga menggunakan SC. Jadi, masalahnya akan diisolasi untuk lingkup tersebut dengan pernyataan penggunaan . Jika Anda mengatakan bahwa seorang programmer pemeliharaan tidak memiliki tanggung jawab untuk membaca dokumen pada modul yang disertakan, saya tidak bisa setuju. Namun, terima kasih telah berkomentar
Axeman

7
Saya tidak mengatakan bahwa mereka tidak memiliki tanggung jawab tetapi itu tidak mungkin menjadi hal pertama yang mereka cari. Tidak pernah melihat modul Komentar Cerdas sebelum saya tidak akan tahu mengapa kode di atas mencetak sesuatu. Saya dapat menghabiskan berhari-hari melewatkan komentar dan bahkan tidak memprosesnya karena komentar seharusnya tidak melakukan apa-apa. Membuat mereka melakukan sesuatu adalah imo yang sangat buruk. Mereka dapat digunakan untuk menghasilkan dokumentasi dll selama mereka tidak mengubah perilaku program.
MikeKulls

4

Looping:

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

Fungsional

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

Tapi untuk keanggunan belaka, saya harus memilih wrang-wrang. Untuk kode saya sendiri, saya akan memilih foreach saya. Atau gunakan Dumper tetro.


3
Tidak ada perbedaan fungsional antara penggunaan foreachdan map. mapharus digunakan untuk transformasi daftar, bukan dalam konteks kosong untuk meniru for-loop
friedo

akan menarik untuk melihat hasil 'byte code' dari masing-masing ... Saya ingin tahu apakah peta lebih atau kurang efisien.
Kera-inago

2

Cara termudah dalam pengalaman saya adalah dengan hanya menggunakan Nilai Dump .

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

Bekerja seperti pesona dan Anda tidak perlu khawatir tentang memformat hash, karena menghasilkan seperti hash debugger Perl (bagus untuk debugging). Plus, Dumpvalue disertakan dengan set modul Perl, jadi Anda tidak perlu mengacaukan CPAN jika Anda berada di belakang semacam proxy kejam (seperti saya di tempat kerja).


1

Jika Anda ingin menjadi orang yang bertele-tele dan menjaganya tetap pada satu baris (tanpa menggunakan statemen dan shebang), maka saya akan menyortir piggy dari jawaban tetromino dan menyarankan:

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

Tidak melakukan sesuatu yang istimewa selain menggunakan hash anonim untuk melewati variabel temp;)


OP mengatakan dia memiliki "hash saya" yang perlu dicetak. Jawaban ini hanya kepintaran untuk kepentingannya sendiri
justintime

OP berharap untuk melakukannya dalam satu baris. Baru saja menunjukkan cara satu garis melakukannya. Jadi itu layak untuk down-vote?
Kyle Walsh

1

Saya menambahkan satu ruang untuk setiap elemen hash untuk melihatnya dengan baik:

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

1

Saya sangat suka mengurutkan kunci dalam satu kode liner:

print "$_ => $my_hash{$_}\n" for (sort keys %my_hash);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.