使用Perl将CSV数据转换为哈希

使用Perl将CSV数据转换为哈希,perl,csv,hash,Perl,Csv,Hash,我是Perl新手。我正在尝试从CSV文件创建哈希 我的CSV数据当前如下所示: id、姓名、头衔、评级 123,安德鲁,第1,3册 1221年,亚伯拉罕,第2、4册 43,安妮,第三册,第1册 我想让肉馅看起来像这样 $reviews={ 回顾=>[ { id=>[123], name=>[Andrew], 书名=>[“第一册”], 评级=>[3], }, { id=>[1221], name=>[Abraham], 书名=>[“第二册”], 评级=>[4]] }, { id=>[43], 姓

我是Perl新手。我正在尝试从CSV文件创建哈希

我的CSV数据当前如下所示:

id、姓名、头衔、评级
123,安德鲁,第1,3册
1221年,亚伯拉罕,第2、4册
43,安妮,第三册,第1册
我想让肉馅看起来像这样

$reviews={
回顾=>[
{
id=>[123],
name=>[Andrew],
书名=>[“第一册”],
评级=>[3],
},
{
id=>[1221],
name=>[Abraham],
书名=>[“第二册”],
评级=>[4]]
},
{
id=>[43],
姓名=>[Annie],
书名=>[“第三册”],
版本=>[1],
},
]
};
但是我得到了这个

$VAR1={
'123' => { 
“name”=>“Andrew”,
“标题”=>“第1册”,
'id'=>'123',
“评级”=>“3”,
},
'1221' => { 
'姓名'=>'亚伯拉罕',
“标题”=>“第二册”,
'id'=>'1221',
“评级”=>“4”,
},
'43' => { 
“姓名”=>“安妮”,
“标题”=>“第三册”,
'id'=>'43',
“评级”=>“1”,
}
};
这是我目前使用的代码。我的CSV在
output.CSV
文件中,我正在
hashr.txt
文件中打印哈希值

my%hash;
打开(结果,“output.csv”)| | die“无法打开output.csv:$!\n”;
打开(HASHR,“+>HASHR.txt”)| | die“无法打开HASHR.txt:$!\n”;
而(){
最后一个if/id/
}
my$labels=$\#保存最后一行以标记关键点
印章$标签;
而(){
咀嚼;
my@array=split/,/;
我的$index=0;
我的%h=映射{$\=>$array[$index++]}拆分(“,”,$labels);
#my$key=“review”;
#$hash{$key}=\%h;
$hash{$array[0]}=\%h;
}
打印转储程序(\%hash);
打印HASHR转储程序(\%hash);
接近结果;

您想要的数据结构很奇怪,但下面的内容应该会让您更接近您所说的想要的内容

您可能可以使用的复习工具来了解有关复杂数据结构的更多信息

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

我已经多年没有接触perl了,所以语法可能有点离题了,但要点是您希望将生成的值放入一个数组中,然后将其全部封装到一个数组中在perl中,哪一个是匿名数组?我认为您已经拥有的比您想要的设计要好得多。您是否意识到,
$reviews
是一个单元素散列,而您的散列值是一个单元素数组?因此,要访问第二次审阅的
name
字段,您必须编写
$reviews->{review}[1]{name}[0]
。除非有更多数据需要存储在同一结构中,否则如果
$reviews
是数组引用,而哈希值是纯字符串,不是更好吗?这样,访问同一个项目就像
$reviews->[1]{name}
,这更简单,也更不容易出现错误。@Borodin我意识到我可能不应该这样做,但有时我会调整我的编码风格首选项,只是为了迎合语法更高的要求。我可能最常使用正则表达式来实现这一点,当语法高亮器像上面那样在拆分中使用
/
而不是分号时,我更倾向于使用
s{}{}
。我想,不能在任何地方都获胜:)我很同情,但Perl以其最佳猜测解析而臭名昭著,一个合适的高亮程序必须编译代码才能使其正确。这使得无法正确突出显示任何未编译的内容。我倾向于编写最佳实践代码,并在必要时使用
删除突出显示。毕竟,荧光笔肯定会把
\uuuuu数据\uuuu
中的任何东西弄得一团糟。在任何情况下,默认高亮显示都会使用如此柔和的颜色,我通常会忽略它。是的,糟糕的语法高亮显示是很小的,但偶尔它仍然会让我感到不舒服。问题是,有更好的解析器,就像我的编辑器Sublime Text使用的解析器一样。几乎让我想贡献自己,但现在不太可能在那里投入时间:)
[
  { 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"] },
]
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 );