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'에 특히 닝, 다양한 데이터 :: 덤퍼 옵션으로 볼 수도 있습니다
plusplus

1
@JonathanDay 나는 그 세부 사항을 놓치고 도움이되었습니다! 감사!
Sos

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
Sleazy : "@_ \ n"인쇄 중 @_ = 각 % h
FMc

난 당신이 의미하는 생각 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 % 느려집니다!
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"
    }
}

색상을 갖는 것은 "정말"이지만, 내가 잘못하고 있거나 "use Data :: Printer; p % var;" 해시로 화살표를 인쇄하지 않으며 저와 같은 초보자에게 도움이됩니다
Sos

@Sosi 답변의 출력을 보면 =>예상대로 출력되지 않는 것을 알 수 있습니다. 대신 항상 키, 여러 공백 및 값을 인쇄합니다. 출력을 사람이 스캔하는 데 도움이됩니다.
Brad Gilbert

12

대답은 해시의 내용에 따라 다릅니다. 간단한 해시를 가지고 있다면

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

또는

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

그러나 참조로 채워진 해시가 있으면 해당 참조를 걸고 합리적인 출력을 생성 할 수있는 무언가가 생깁니다. 이러한 참조를 일반적으로 직렬화라고합니다. 다른 스타일을 구현하는 많은 모듈이 있으며, 가장 많이 사용되는 모듈은 다음과 같습니다.

사실로 인해 Data::Dumper핵심 펄 라이브러리의 일부입니다, 아마 가장 인기가있다; 그러나 다른 모듈 중 일부는 제공 할만한 좋은 기능이 있습니다.


10

내가 좋아하는 것 : Smart :: Comments

use Smart::Comments;
# ...

### %hash

그게 다야.


5
죄송합니다, 실제 기능에 대한 의견을 가로채는 물건에 대해 저에게 투표하십시오. 유지 보수 프로그래머는 하루 종일 그러한 코드가 예상치 못한 것을 인쇄하는 이유를 알아 내기 위해 노력할 수 있습니다.
MikeKulls

2
@MikeKulls, np. 소스 필터이므로 이해합니다. 또한 프로덕션 준비에 넣지 않은 모든 모듈을 검사하는 스크립트를 작성하지 않았으므로 use Smart::Comments그 관점에서도 볼 수 있습니다. 그러나 카운터에 Smart::Comments대해서는 범위지정된 모듈 로 잘 작동하므로 SC 를 사용 하지 않는 모듈에는 출력 동작이 없어야합니다 . 따라서 문제는 use 문을 사용 하여 해당 범위로 격리됩니다 . 유지 보수 프로그래머가 포함 된 모듈에 대한 문서를 읽을 책임이 없다고 말하는 경우에는 동의하지 않습니다. 댓글을 주셔서 감사합니다
Axeman

7
나는 그들이 책임이 없다고 말하지는 않지만 그들이 가장 먼저 찾는 것은 아닐 것입니다. 스마트 주석 모듈을 본 적이 없어서 위의 코드가 왜 인쇄되고 있는지 알 수 없었습니다. 나는 주석을 건너 뛰고 주석을 처리하지 않아도 며칠을 보낼 수 있습니다. 그들에게 무언가를하는 것은 매우 나쁜 일입니다. 프로그램의 동작을 변경하지 않는 한 문서 등을 생성하는 데 사용할 수 있습니다.
MikeKulls

4

루핑 :

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

기능의

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

그러나 순전히 우아함을 위해서는 wrang-wrang 's를 선택해야합니다. 내 코드의 경우 foreach를 선택합니다. 또는 tetro의 덤퍼 사용.


3
당신의 사용 사이의 기능적 차이가 없다 foreach하고 map. mapA에 대한 루프 에뮬레이트되지 공극 맥락에서, 목록 변환에 대한 표기
friedo

각각의 '바이트 코드'결과를 보는 것이 흥미로울 것입니다 ...지도가 다소 효율적인지 궁금합니다.
Ape-inago

2

내 경험에서 가장 쉬운 방법은 Dumpvalue 만 사용하는 입니다.

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

매력처럼 작동하며 Perl 디버거가 출력하는 것처럼 해시 형식을 지정할 필요가 없습니다 (디버깅에 적합). 또한 Dumpvalue는 Perl 모듈의 스톡 세트에 포함되어 있으므로 어떤 종류의 draconian 프록시를 사용하고 있다면 CPAN을 망칠 필요가 없습니다.


1

당신이 pedantic하고 싶어하고 (사용 진술과 shebang없이) 한 줄로 유지하려면, 나는 tetromino의 대답에서 일종의 돼지를 다시 제안하고 제안 할 것입니다 :

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

임시 변수를 건너 뛰기 위해 익명 해시를 사용하는 것 외에는 특별한 일을하지 않습니다.)


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.