ฉันจะพิมพ์เนื้อหาของแฮชใน 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
โปสเตอร์ต้นฉบับอาจต้องการดูข้อมูลต่างๆ :: ตัวเลือก Dumper โดยเฉพาะการเปลี่ยน 'Sortkeys' จะมีประโยชน์มาก
plusplus

1
@JonathanDay ฉันไม่มีรายละเอียดนั้นและมันมีประโยชน์ ขอบคุณ!
Sos

5
การเพิ่มเครื่องหมายทับหน้า% หมายความว่าอย่างไร
แชมพู

16
ตัวดำเนินการ @shampoo slash สร้างการอ้างอิงเล็กน้อยเช่นตัว&ดำเนินการใน C และ C ++ เหตุผลที่มันเป็นเรื่องสำคัญในบริบทนี้คือว่าใน Perl ถ้าคุณเรียกใช้ฟังก์ชันที่มีค่าแฮชเป็นอาร์กิวเมนต์, ค่าแฮชที่ได้รับ listified และขยายเข้าสู่การขัดแย้งหลาย - ดังนั้นจะเทียบเท่ากับ%hsh=("a" => 1, "b" => 2); foo(%hsh); foo("a", 1, "b", 2)หากคุณต้องการให้ฟังก์ชั่นทำงานกับแฮชตัวเองคุณต้องผ่านการอ้างอิงถึงแฮช: foo(\%hsh);ดูperldoc.perl.org/perlsub.html#Pass-by-Reference
tetromino

63

ง่าย:

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

สง่า แต่ช้ากว่าจริง 30% (!):

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

9
ไม่น่าเชื่อ: พิมพ์ "@_ \ n" ขณะที่ @_ = แต่ละ% h
FMc

ฉันคิดว่าคุณหมายถึงprint "$_ $h{$_}\n" for (keys %h);, $kไม่ได้อยู่ในตัวอย่างที่
Chas Owens

4
นอกจากนี้เกณฑ์มาตรฐานก่อนทำการเรียกร้องเกี่ยวกับประสิทธิภาพ (หรืออย่างน้อยมีคุณสมบัติตามประเภทของประสิทธิภาพที่คุณกำลังพูดถึง) การforวนซ้ำเร็วกว่าwhileแป้นอย่างน้อย 10,000 แป้น: gist.github.com/151792
Chas Owens

1
แน่นอนว่าคุณถูกต้อง: $ k แต่มันมีประสิทธิภาพมากกว่าใน Perl 6! :) ใช่คุณพูดถูก ฉันไม่เคยคิดที่จะเพิ่มประสิทธิภาพหรือโปรไฟล์ Perl ของฉัน แต่ฉันดีใจที่ได้เรียนรู้สิ่งนี้ แน่นอนว่าแต่ละคนควรมีประสิทธิภาพมากกว่า (เพราะไม่มีคีย์แฮชพิเศษในการค้นหา) แต่มันช้ากว่า ~ 30%!
Jonathan Graehl

สวัสดี Jonathan Graehl ขออภัยยังไม่เข้าใจ คุณกำลังบอกว่าแต่ละคนจะช้ากว่า ~ 30% ตามอะไร เป็นทุกครั้งหรือไม่สำหรับทุกสถานการณ์ช่องว่างที่ 30%?
Carlos Sá


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

(ผลลัพธ์อาจมีสีสันมากกว่าบนเทอร์มินัล)

ซึ่งแตกต่างจากตัวอย่างอื่น ๆ ที่ฉันได้แสดงไว้ที่นี่สิ่งนี้ได้รับการออกแบบอย่างชัดเจนเพื่อวัตถุประสงค์ในการแสดงผลเท่านั้น ซึ่งจะปรากฏขึ้นได้ง่ายขึ้นหากคุณทิ้งโครงสร้างของตัวแปรที่ผูกหรือว่าของวัตถุ

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

มีสีคือ "เรียบร้อย" แต่ฉันกำลังทำอะไรผิดหรือใช้ "ใช้ Data :: Printer; p% var;" ไม่พิมพ์ลูกศรเป็นแฮชและสำหรับมือใหม่อย่างฉันที่ช่วยฉันได้
Sos

@Sosi หากคุณดูผลลัพธ์ในคำตอบคุณจะเห็นว่ามันไม่ได้ออกตามที่=>คุณคาดหวัง มันมักจะพิมพ์กุญแจช่องว่างหลาย ๆ และค่า ซึ่งช่วยให้มนุษย์สแกนมากกว่าผลลัพธ์
Brad Gilbert

12

คำตอบขึ้นอยู่กับสิ่งที่อยู่ในแฮชของคุณ หากคุณมีแฮชแบบง่าย ๆ

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

หรือ

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

จะทำ แต่ถ้าคุณมีแฮชที่เต็มไปด้วยการอ้างอิงคุณจะทำสิ่งที่สามารถเดินการอ้างอิงเหล่านั้นและสร้างผลลัพธ์ที่สมเหตุสมผล การเดินอ้างอิงนี้ปกติเรียกว่าการทำให้เป็นอันดับ มีโมดูลจำนวนมากที่ใช้สไตล์ที่แตกต่างซึ่งเป็นที่นิยมมากขึ้นคือ:

เนื่องจากความจริงที่ว่าData::Dumperเป็นส่วนหนึ่งของห้องสมุด Perl หลักมันน่าจะเป็นที่นิยมมากที่สุด; อย่างไรก็ตามโมดูลอื่น ๆ บางอย่างมีสิ่งที่ดีมากที่จะนำเสนอ


10

สิ่งที่ฉันชอบ: สมาร์ท :: ความคิดเห็น

use Smart::Comments;
# ...

### %hash

แค่นั้นแหละ.


5
ขออภัยลงคะแนนจากฉันสำหรับสิ่งที่จี้ความคิดเห็นสำหรับการทำงานจริง โปรแกรมเมอร์บำรุงรักษาอาจใช้เวลาทั้งวันเพื่อพยายามหาสาเหตุที่รหัสเช่นนั้นกำลังพิมพ์สิ่งที่ไม่คาดคิด
MikeKulls

2
@ MikeKulls, np มันเป็นตัวกรองซอร์สดังนั้นฉันเข้าใจ นอกจากนี้เมื่อมีสคริปต์เป็นลายลักษณ์อักษรที่ตรวจสอบทุกโมดูลที่ฉันใส่ในการเตรียมการผลิตที่ไม่ได้ทำuse Smart::Commentsฉันก็เห็นมันจากมุมมองนั้น แต่สำหรับตัวนับSmart::Commentsนั้นค่อนข้างทำตัวเป็นโมดูลที่กำหนดขอบเขตไม่ควรมีพฤติกรรมการส่งออกในโมดูลใด ๆ ที่ไม่ได้ใช้ SC ดังนั้นปัญหาจะถูกแยกออกไปขอบเขตที่มีคำสั่งการใช้งาน หากคุณกำลังบอกว่าโปรแกรมเมอร์บำรุงรักษาไม่มีความรับผิดชอบในการอ่านเอกสารเกี่ยวกับโมดูลที่รวมไว้ฉันไม่สามารถตกลงได้ ยังคงขอบคุณที่แสดงความคิดเห็น
Axeman

7
ฉันไม่ได้บอกว่าพวกเขาไม่มีความรับผิดชอบ แต่ก็ไม่น่าจะเป็นสิ่งแรกที่พวกเขามองหา ไม่เคยเห็นโมดูลสมาร์ทคอมเม้นท์มาก่อนเลยไม่รู้ว่าทำไมโค้ดด้านบนถึงกำลังพิมพ์ออกมา ฉันสามารถใช้เวลาหลายวันข้ามความคิดเห็นและไม่ได้ดำเนินการเพราะความคิดเห็นไม่ควรทำอะไรเลย การทำให้พวกเขาทำอะไรบางอย่างนั้นแย่มาก สามารถใช้สำหรับการสร้างเอกสาร ฯลฯ ตราบใดที่ไม่เปลี่ยนแปลงพฤติกรรมของโปรแกรม
MikeKulls

4

วนรอบ:

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

การทำงาน

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

แต่เพื่อความสง่างามอย่างแท้จริงฉันจะต้องเลือกของ Wrang-wrang สำหรับรหัสของฉันเองฉันจะเลือก foreach ของฉัน หรือเทตโตรที่ใช้รถเทเปอร์


3
ไม่มีความแตกต่างระหว่างการใช้การทำงานของของคุณและforeach ควรจะใช้สำหรับการแปลงรายการไม่ได้อยู่ในบริบทที่จะเลียนแบบเป็นโมฆะสำหรับวงmapmap
friedo

มันน่าสนใจที่จะเห็นผลลัพธ์ 'รหัสไบต์' ของแต่ละ ... ฉันสงสัยว่าแผนที่นั้นมีประสิทธิภาพมากขึ้นหรือน้อยลง
Ape-inago

2

วิธีที่ง่ายที่สุดในประสบการณ์ของฉันเป็นเพียงแค่ใช้Dumpvalue

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

ใช้งานได้อย่างมีเสน่ห์และคุณไม่ต้องกังวลเกี่ยวกับการจัดรูปแบบแฮชเนื่องจากมันให้ผลลัพธ์เหมือนกับที่ดีบักเกอร์ Perl ใช้ (เหมาะสำหรับการดีบั๊ก) นอกจากนี้ Dumpvalue จะรวมอยู่ในชุดหุ้นของโมดูล Perl ดังนั้นคุณไม่ต้องยุ่งกับ CPAN ถ้าคุณอยู่หลัง draconian proxy (เหมือนกับที่ฉันทำงาน)


1

หากคุณต้องการที่จะอวดความคิดและเก็บไว้ในบรรทัดเดียว (โดยไม่ต้องใช้คำสั่งและ Shebang) แล้วฉันจะเรียงลำดับหมูออกจากคำตอบของ tetromino และแนะนำ:

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

ไม่ทำอะไรเป็นพิเศษนอกจากการใช้แฮชไม่ระบุชื่อเพื่อข้ามตัวแปร temp;)


OP บอกว่าเขามี "แฮชของฉัน" ที่ต้องการการพิมพ์ คำตอบนี้เป็นเพียงความฉลาดเพื่อประโยชน์ของตัวเอง
justintime

OP หวังว่าจะทำได้ในหนึ่งบรรทัด เป็นเพียงการแสดงวิธีการหนึ่งในการทำมัน ดังนั้นจึงมีค่าลงคะแนน?
Kyle Walsh

1

ฉันผนวกหนึ่งช่องว่างสำหรับทุกองค์ประกอบของแฮชเพื่อให้ดูดี:

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

1

ฉันชอบเรียงลำดับคีย์ในหนึ่งรหัสซับ:

print "$_ => $my_hash{$_}\n" for (sort keys %my_hash);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.