如何在Perl中打印哈希的内容?


167

我不断将我的哈希打印为#个存储桶/#个已分配。如何打印哈希的内容?

不使用while循环将是最可取的(例如,单线将是最好的)。

Answers:


253

数据::倾销者是你的朋友。

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

将输出

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

3
原始张贴者还可能希望研究各种Data :: Dumper选项,特别是启用“ Sortkeys”可能非常有用
plusplus 2009年

1
@JonathanDay我错过了那个细节,这很有帮助!谢谢!
Sos 2014年

5
在%前面加上斜杠是什么意思?
洗发水

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
tetromino,

63

简单:

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

优雅,但实际上慢30%(!):

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

9
lea脚

我想你的意思是print "$_ $h{$_}\n" for (keys %h);$k在该示例中不存在。
Chas。欧文斯(Owens)

4
同样,在声明效率(或至少限定您要谈论的效率类型)之前进行基准测试。该for环比速度while达到至少10,000键:gist.github.com/151792
查斯。欧文斯(Owens)

1
当然,您是正确的:$ k。但是在Perl 6中效率更高!:)是的,您也是正确的。我从没想过要实际优化或分析我的Perl,但是我很高兴学习这一点。当然,每个键都应该更有效(因为键上没有多余的哈希查找)。但这要慢30%!
乔纳森·格雷尔

嗨,乔纳森·格雷尔。对不起,还不了解。您是说基于什么,每个速度要慢30%?在每种情况下,每次都有30%的差距吗?
卡洛斯·萨


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 2014年

@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 2013年

7
我并不是说他们没有责任,但这并不是他们所追求的第一件事。在我不知道为什么上面的代码打印出某些内容之前,从未见过Smart Comments模块。我可能要花几天的时间跳过评论,甚至不处理它,因为评论什么都不做。让他们做某事是非常糟糕的事。它们可以用于生成文档等,只要它们不改变程序的行为即可。
MikeKulls 2014年

4

循环播放:

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

功能性

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

但是为了纯粹的优雅,我不得不选择wrang-wrang的。对于我自己的代码,我选择我的foreach。或tetro的自卸车使用。


3
您对foreach和的使用没有功能上的区别mapmap应该用于列表转换,而不是在空上下文中模拟for循环
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

如果您想成为一个学究型的人,并且将其保持在一行(没有使用声明和shebang),那么我会从tetromino的答案中抽出来,并提出以下建议:

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

除了使用匿名哈希跳过temp变量外,不执行任何其他特殊操作;)


OP说他有需要打印的“我的哈希”。这个答案只是出于自己的
智慧

OP希望能够做到这一点。只是显示一种单行方式。所以这值得一票吗?
凯尔·沃尔什

1

我为哈希的每个元素都添加了一个空格,以便对其进行很好的查看:

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

1

我真的很喜欢用一个线性代码对键进行排序:

print "$_ => $my_hash{$_}\n" for (sort keys %my_hash);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.