2014-06-20 4 views
1

Perl을 처음 사용했습니다. CSV 파일에서 해시를 만들려고합니다. Perl을 사용하여 CSV 데이터를 해시로 변환

내 CSV 데이터

는 현재 다음과 같습니다

id,name,title,rating 
123,Andrew,Book 1,3 
1221,Abraham,Book 2,4 
43,Annie,Book 3,1 

나는이

$reviews = { 
    review => [ 
       { 
        id  => [ 123 ], 
        name => [ Andrew ], 
        title => [ "Book 1" ], 
        rating => [ 3 ], 
       }, 
       { 
        id  => [ 1221 ], 
        name => [ Abraham ], 
        title => [ "Book 2" ], 
        rating => [ 4 ]] 
       }, 
       { 
        id  => [ 43 ], 
        name => [ Annie ], 
        title => [ "Book 3" ], 
        edition => [ 1 ], 
       }, 
       ] 
      }; 

처럼 보이도록 해시를하고 싶습니다하지만이 대신

$VAR1 = { 
    '123' => { 
        'name' => 'Andrew', 
        'title' => 'Book 1', 
        'id' => '123', 
        'rating' => '3', 
       }, 
    '1221' => { 
        'name' => 'Abraham', 
        'title' => 'Book 2', 
        'id' => '1221', 
        'rating' => '4', 
       }, 
    '43' => { 
        'name' => 'Annie', 
        'title' => 'Book 3', 
        'id' => '43', 
        'rating' => '1', 
       } 

     }; 

받고 있어요 지금까지 사용하고있는 코드는 다음과 같습니다. 내 CSV는 output.csv 파일에 있고 나는 hashr.txt 파일

my %hash; 
open (RESULTS, "output.csv")|| die "Can't open output.csv: $!\n"; 
open (HASHR, "+>hashr.txt")|| die "Can't open hashr.txt: $!\n"; 

while (<RESULTS>) { 
    last if /id/ 
} 
my $labels = $_; #save last line to label keys 
chop $labels; 

while (<RESULTS>) { 
    chomp; 
    my @array = split /,/; 
    my $index = 0; 
    my %h = map { $_ => $array[$index++]} split(",", $labels); 

    #my $key = "review"; 
    #$hash{$key}=\%h; 

    $hash{ $array[0] } = \%h; 
} 

print Dumper(\%hash); 
print HASHR Dumper(\%hash); 
close RESULTS; 
+1

perl에서 익명 어레이 인 값은 실제로 []입니다. – salparadise

+0

나는 당신이 이미 원하는 디자인보다 훨씬 낫다고 생각합니다. ''$ 리뷰 '는 하나의 요소로 구성된 해쉬이고 해시 값은 하나의 요소로 구성된 배열이라는 것을 알고 있습니까? 따라서 두 번째 리뷰의'name' 필드에 액세스하려면'$ reviews -> {review} [1] {name} [0]'이라고 써야합니다. 같은 구조체에 저장할 필요가있는 데이터가 더 많지 않다면'$ reviews'가 배열 참조이고 해쉬 값이 일반 문자열이라면 더 좋지 않을까요? 그렇게하면 동일한 항목에 접근하는 것이'$ reviews -> [1] {name}'처럼 보이고 버그가 훨씬 간단해질 것입니다. – Borodin

답변

1

원하는 데이터 구조가 이상하다에 해시를 인쇄하지만, 당신이 당신이 원하는 말을 가까이해야 다음과 같은거야.

복소수 데이터 구조에 대해 자세히 알아 보려면 perldsc의 리 프레저를 사용할 수 있습니다.

use strict; 
use warnings; 

my $header = <DATA>; 
chomp $header; 
my @headers = split /,/, $header; 

my @records; 
while (<DATA>) { 
    chomp; 
    my @cols = split /,/; 
    my %hash; 
    @hash{@headers} = map [$_], @cols; 
    push @records, \%hash; 
} 

use Data::Dump; 
dd \@records; 

__DATA__ 
id,name,title,rating 
123,Andrew,Book 1,3 
1221,Abraham,Book 2,4 
43,Annie,Book 3,1 

출력 : 나는 펄 감동 한 이후 그 구문은 아마 해제 방법이지만 요점은 당신이에 생성 된 값을 배치 할 것이다 그래서 그것은 년

[ 
    { id => [123], name => ["Andrew"], rating => [3], title => ["Book 1"] }, 
    { id => [1221], name => ["Abraham"], rating => [4], title => ["Book 2"] }, 
    { id => [43], name => ["Annie"], rating => [1], title => ["Book 3"] }, 
] 
+0

@ Borodin 아마 이런 일을해서는 안되는 것을 알았지 만 구문 하이 라이터를 수용하기 위해 코딩 스타일 설정을 조정할 때가 있습니다. 문법 형광펜이 위와 같이'/'로 쪼갤 때's {///}에 비해's {} {}'에 더 강하게 기대어 정규 표현식을 사용하는 것이 가장 많습니다 세미콜론. 도처에서 이길 수는 없다 : – Miller

+0

나는 공감하지만, Perl은 파싱을 가장 잘 추측하고 악명 높은 적절한 형광펜이 코드를 컴파일해야 컴파일 할 수있다. 이로 인해 컴파일되지 않는 항목을 올바르게 강조 표시 할 수 없습니다. 베스트 프랙티스 코드를 작성하고 필요한 경우' '을 사용하여 강조 표시를 제거하는 경향이 있습니다. 결국, 형광펜은'__DATA__'에서 무엇이든 엉망으로 만든다. 어쨌든 기본 강조 표시는 일반적으로 간과하는 음소거 된 색상을 사용합니다. – Borodin

+0

예, 불충분 한 구문 강조는 매우 사소하지만 여전히 가끔 버그입니다. 문제는 필자의 편집자 Sublime Text에서 사용하는 파서와 같은 더 나은 파서가 있다는 것입니다. 거의 내가''Google Prettifier' (http://google-code-prettify.googlecode.com/svn/trunk/README.html)에 기여하고 싶지만 지금은 내 시간을 투자하지 않을 것입니다. :) – Miller

0
review => [ 
      { 
       id  => [ 123 ], 
       name => [ Andrew ], 
       title => [ "Book 1" ], 
       rating => [ 3 ], 
      }, 

'123' => { 
       'name' => 'Andrew', 
       'title' => 'Book 1', 
       'id' => '123', 
       'rating' => '3', 
      }, 


my %h = map { $_ => $array[$index++]} split(",", $labels); 


to 

my %h = map { $_ => @{$array[$index++]}} split(",", $labels); 

을이었다 배열을 완성한 다음 배열로 묶으십시오.

관련 문제