Perl: With Text::CSV can I write out a hash ref?

自闭症网瘾萝莉.ら 提交于 2020-01-05 07:12:55

问题


I have a Perl script that reads in a CSV file, changes the columns names of the original, adds new ones (output CSV column names are stored in the array, header_line), adds new field values for each row read, and then writes out a new CSV file.

Thanks to a comment by @harleypig on my last question, I'd like to use:

$csv_i->column_names( @header_line);
$row = $csv_i->getline_hr($fh_i)

because this lets me easily access row fields using meaningful names rather than magic numbers. For example:

$row->{ 'name' } = get_fullname($row->{ 'name' });

The only problem now is, what's the best way to write out the line? Previously, I used:

$csv_o->print( $fh_o, $row ); 

But that fails because it expects an array ref. How do I write out the hash ref using the csv_o object?


回答1:


Use a hash slice:

$csv_o->print( $fh_o, [ @$row{@header_line} ] );

The map version works too, but the slice is faster:

use Benchmark 'cmpthese';

my @header_line = qw(a b c d e f g);
my $row = { map { $_ => $_ } @header_line };

my $array;

cmpthese(-3, {
  slice => sub {
    $array = [ @$row{@header_line} ];
  },

 map => sub {
    $array = [ map { $row->{$_} } @header_line ];
  },
});

gives me:

          Rate   map slice
map   282855/s    --  -42%
slice 487898/s   72%    --



回答2:


From a quick look at the docs, I don't think you can easily. You'd have to turn the hashref back into the (column-ordered) array, something like:

$csv_o->print( $fh_o, [ map { $row->{$_} } @header_line ] ); 


来源:https://stackoverflow.com/questions/4163048/perl-with-textcsv-can-i-write-out-a-hash-ref

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!