Làm cách nào tôi có thể in nội dung của hàm băm trong Perl?


167

Tôi tiếp tục in hàm băm của mình dưới dạng # xô / # được phân bổ. Làm cách nào để in nội dung băm của tôi?

Không sử dụng một whilevòng lặp sẽ là tốt nhất (ví dụ, một lớp lót sẽ là tốt nhất).

Câu trả lời:


253

Dữ liệu :: Dumper là bạn của bạn.

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

sẽ xuất

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

3
người đăng ban đầu cũng có thể muốn xem xét các tùy chọn Data :: Dumper khác nhau, đặc biệt là bật 'Sortkeys' có thể rất hữu ích
plusplus

1
@JonathanDay Tôi đã bỏ lỡ chi tiết đó và nó rất hữu ích! Cảm ơn!
Sos

5
Có nghĩa là thêm một dấu gạch chéo ở phía trước%?
gội đầu

16
Toán tử slash @shampoo tạo một tham chiếu, hơi giống &toán tử trong C và C ++. Lý do nó quan trọng trong ngữ cảnh này là vì trong Perl, nếu bạn gọi một hàm có giá trị băm là đối số, thì giá trị băm đó được liệt kê và mở rộng thành nhiều đối số - vì vậy %hsh=("a" => 1, "b" => 2); foo(%hsh);sẽ tương đương với foo("a", 1, "b", 2). Thay vào đó, nếu bạn muốn hàm hoạt động trên chính hàm băm, bạn cần chuyển một tham chiếu đến hàm băm: foo(\%hsh);Xem perldoc.perl.org/perlsub.html#Pass-by-Reference
tetromino 27/1/2016

62

Dễ dàng:

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

Thanh lịch, nhưng thực tế chậm hơn 30% (!):

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


Tôi nghĩ bạn có nghĩa là print "$_ $h{$_}\n" for (keys %h);, $kkhông tồn tại trong ví dụ đó.
Chas. Owens

4
Ngoài ra, điểm chuẩn trước khi đưa ra tuyên bố về hiệu quả (hoặc ít nhất là đủ điều kiện loại hiệu quả mà bạn đang nói đến). Các forvòng lặp là nhanh hơn so với whiletiêu chuẩn tối thiểu 10.000 phím: gist.github.com/151792
Chas. Owens

1
Tất nhiên bạn đúng rồi: $ k. Nhưng nó hiệu quả hơn trong Perl 6! :) Vâng, bạn cũng đúng về điều đó. Tôi sẽ không bao giờ nghĩ sẽ thực sự tối ưu hóa hoặc lập hồ sơ Perl của mình, nhưng tôi rất vui khi biết điều này. Tất nhiên, mỗi cái sẽ hiệu quả hơn (vì không có thêm tra cứu băm trên khóa). Nhưng nó chậm hơn ~ 30%!
Jonathan Graehl

Xin chào, Jonathan Graehl. Xin lỗi, vẫn chưa hiểu. Bạn đang nói rằng mỗi cái chậm hơn ~ 30% dựa trên cái gì? Là mọi lúc, cho mọi tình huống, khoảng cách 30%?
Carlos Sá


24

Đối với mục đích gỡ lỗi tôi sẽ thường sử dụng YAML.

use strict;
use warnings;

use YAML;

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

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

Kết quả trong:

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

Những lần khác tôi sẽ sử dụng Data::Dump. Bạn không cần phải đặt nhiều biến để xuất nó thành một định dạng đẹp hơn bạn làm Data::Dumper.

use Data::Dump = 'dump';

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

Gần đây tôi đã sử dụng Data::Printerđể gỡ lỗi.

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

(Kết quả có thể nhiều màu sắc hơn trên một thiết bị đầu cuối)

Không giống như các ví dụ khác tôi đã trình bày ở đây, ví dụ này được thiết kế rõ ràng chỉ dành cho mục đích hiển thị. Điều này xuất hiện dễ dàng hơn nếu bạn loại bỏ cấu trúc của một biến bị ràng buộc hoặc của một đối tượng.

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

có màu sắc là "gọn gàng", nhưng tôi đang làm gì đó sai hoặc sử dụng "sử dụng Dữ liệu :: Máy in; p% var;" không in các mũi tên trong băm và đối với một người mới như tôi sẽ giúp
Sos

@Sosi Nếu bạn nhìn vào đầu ra trong câu trả lời, bạn sẽ thấy rằng nó không xuất ra =>như bạn mong đợi. Thay vào đó, nó luôn luôn in khóa, một vài khoảng trắng và sau đó là giá trị. Điều này giúp một con người quét qua đầu ra.
Brad Gilbert

12

Câu trả lời phụ thuộc vào những gì trong hàm băm của bạn. Nếu bạn có một hàm băm đơn giản thì đơn giản

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

hoặc là

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

sẽ làm được, nhưng nếu bạn có một hàm băm được điền với các tham chiếu, bạn sẽ có thứ gì đó có thể dẫn các tham chiếu đó và tạo ra một đầu ra hợp lý. Việc đi bộ này của các tài liệu tham khảo thường được gọi là tuần tự hóa. Có nhiều mô-đun triển khai các kiểu khác nhau, một số mô-đun phổ biến hơn là:

Do thực tế Data::Dumperlà một phần của thư viện Perl cốt lõi, nó có lẽ là phổ biến nhất; tuy nhiên, một số mô-đun khác có những thứ rất tốt để cung cấp.


10

Yêu thích của tôi: Thông minh :: Nhận xét

use Smart::Comments;
# ...

### %hash

Đó là nó.


5
Xin lỗi, bỏ phiếu từ tôi cho những thứ chiếm đoạt bình luận cho chức năng thực tế. Một lập trình viên bảo trì có thể dành cả ngày để cố gắng tìm ra lý do tại sao mã như thế lại in ra những thứ không mong muốn.
MikeKulls

2
@MikeKulls, np. Đó là một bộ lọc nguồn, vì vậy tôi hiểu. Ngoài ra, có các tập lệnh viết kiểm tra mọi mô-đun mà tôi đưa vào chuẩn bị sản xuất mà nó không có use Smart::Comments, tôi cũng thấy nó theo quan điểm đó. Nhưng đối với quầy, Smart::Commentshoạt động khá tốt như một mô-đun có phạm vi , không nên có hành vi đầu ra trong bất kỳ mô-đun nào không sử dụng SC. Vì vậy, vấn đề sẽ được tách biệt với các phạm vi đó bằng một tuyên bố sử dụng . Nếu bạn nói rằng một lập trình viên bảo trì không có trách nhiệm đọc tài liệu trên các mô-đun đi kèm, tôi không thể đồng ý. Tuy nhiên, cảm ơn vì đã bình luận
Axeman 18/12/13

7
Tôi không nói rằng họ không có trách nhiệm nhưng dường như đó không phải là điều đầu tiên họ tìm kiếm. Chưa bao giờ thấy mô-đun Nhận xét thông minh trước khi tôi không biết lý do tại sao đoạn mã trên lại in ra thứ gì đó. Tôi có thể dành nhiều ngày để bỏ qua bình luận và thậm chí không xử lý nó vì bình luận không nên làm gì. Làm cho họ làm một cái gì đó là imo rất xấu. Chúng có thể được sử dụng để tạo tài liệu, vv miễn là chúng không làm thay đổi hành vi của chương trình.
MikeKulls

4

Vòng lặp:

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

Chức năng

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

Nhưng để thanh lịch hơn, tôi phải chọn wrang-wrang. Đối với mã riêng của tôi, tôi sẽ chọn foreach của tôi. Hoặc sử dụng Dumper của tetro.


3
Không có sự khác biệt về chức năng giữa việc sử dụng foreachmap. mapnên được sử dụng cho các phép biến đổi danh sách, không phải trong bối cảnh trống để mô phỏng một vòng lặp
Friedo

Sẽ rất thú vị khi xem kết quả 'mã byte' của mỗi ... Tôi tự hỏi liệu bản đồ có hiệu quả hơn hay kém hơn.
Ape-inago

2

Cách dễ nhất trong kinh nghiệm của tôi là chỉ sử dụng Dumpvalue .

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

Hoạt động như một bùa mê và bạn không phải lo lắng về việc định dạng hàm băm, vì nó xuất ra nó giống như trình gỡ lỗi Perl (rất tốt cho việc gỡ lỗi). Thêm vào đó, Dumpvalue được bao gồm trong bộ mô-đun Perl, vì vậy bạn không phải gặp rắc rối với CPAN nếu bạn đứng sau một loại proxy hà khắc nào đó (như tôi đang làm việc).


1

Nếu bạn muốn trở thành người phạm tội và giữ nó thành một dòng (không sử dụng câu lệnh và shebang), thì tôi sẽ loại bỏ câu trả lời của tetromino và đề nghị:

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

Không làm gì đặc biệt ngoài việc sử dụng hàm băm ẩn danh để bỏ qua biến tạm thời;)


OP nói rằng anh ta có "băm của tôi" cần in. Câu trả lời này chỉ là sự thông minh vì lợi ích của chính nó
ngay trong

OP đã hy vọng làm điều đó trong một dòng. Chỉ hiển thị một cách làm một dòng. Vì vậy, đó là giá trị của một phiếu bầu xuống?
Kyle Walsh

1

Tôi nối thêm một khoảng trống cho mọi phần tử của hàm băm để thấy rõ:

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

1

Tôi thực sự muốn sắp xếp các khóa trong một mã lót:

print "$_ => $my_hash{$_}\n" for (sort keys %my_hash);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.