我正在尝试编写一个脚本,将从(非常大的).csv中的数据列分离到单个列表中,以便稍后使用Text::CSV_XS库。获取单个列没有问题,但我似乎无法使用foreach循环遍历列列表。
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV_XS;
use 5.18.2;
my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1 });
open my $fh, "<", "/users/whoever/test_csv.csv" or die "$!";
sub column_grabber {
foreach my $column (@_) {
my @data = map { $_->[$column] } @{$csv->getline_all ($fh)};
return @data;
}
}
my @column_numbers = (1,2,3,4);
my @collected_data = column_grabber(@column_numbers);
close $fh or die "$!";
调用此子例程以获取列列表,只给出了预期列表中的第一列,但列表中没有以下列。一些故障排除显示@_正在查看我通过的整个列表。
通过省略return语句,foreach循环遍历@ids中传递的所有列,但是我没有得到@data的输出。
循环中是否有某些行为我没有考虑到?也许它与map()语句有关?
所以在玩了一段时间并重新思考一下之后,我已经解决了我的问题。
@column_numbers
就好了
子例程并将标量传递给&column_grabber
。这节省了
当我真的不需要时,我会迷失在参考海洋中
担心这个小剧本。所以现在我的功能脚本如下所示:
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV_XS;
use 5.18.2;
sub column_grabber {
my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1 });
open my $fh, "<", "/users/whoever/test_csv.csv" or die "$!";
my $column = shift @_;
my @data = map { $_->[$column] } @{$csv->getline_all ($fh)};
return @data;
close $fh or die "$!";
}
my @column_numbers = (1,2,3,4);
foreach my $column(@column_numbers){
my @collected_data = &column_grabber($column);
...
}
感谢评论者的意见和帮助。
答案 0 :(得分:2)
请注意,@data
(此处重命名为@rows
或$rows
)的每个元素都应该是对所选字段数组的引用。
my @rows;
while ( my $row = $csv->getline($fh) ) {
push @rows, [ @{ $row }[@column_numbers] ];
}
或
my $rows = $csv->getline_all($fh);
@_ = @{ $_ }[@column_numbers] for @$rows;
或
my @rows = map { [ @{ $_ }[@column_numbers] ] } @{ $csv->getline_all($fh) };