2010-11-12 44 views
1

J'ai un script Perl qui lit dans un fichier CSV, change les noms des colonnes de l'original, en ajoute de nouveaux (les noms des colonnes CSV sont stockés dans le tableau, header_line), ajoute de nouvelles valeurs de champs pour chaque ligne lue, puis écrit un nouveau fichier CSV.Perl: Avec le texte :: CSV puis-je écrire une référence de hachage?

Merci à un commentaire par @harleypig sur mon dernier question, je voudrais utiliser:

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

parce que cela me permet de champs de ligne facilement accès à l'aide des noms significatifs plutôt que des chiffres magiques. Par exemple:

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

Le seul problème est maintenant, quelle est la meilleure façon d'écrire la ligne? Auparavant, j'ai utilisé:

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

Mais cela échoue car il attend un tableau ref. Comment puis-je écrire le hash ref en utilisant l'objet csv_o?

Répondre

4

Utilisez un hash slice:

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

Les travaux map la version aussi, mais la tranche est plus rapide :

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 ]; 
    }, 
}); 

me donne:

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

J'oublie toujours les tranches de hachage pour une raison quelconque ... – plusplus

+0

Fonctionne très bien. Merci beaucoup. – FunLovinCoder

1

D'un coup d'œil sur les docs, je ne pense pas que vous pouvez facilement. Il faudrait tourner la hashref de nouveau dans la (colonne ordonnée) tableau, quelque chose comme:

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

Merci, cela fonctionne bien aussi; ira avec la tranche de hachage bien que cela semble avoir le bord. – FunLovinCoder