如何解决在子例程中...使用return获得数组的某些元素
我试图在子例程中返回一些数组元素。它只给我最后一个dd 4 13
这是我的csv
aa,1,no,ed,8
bb,2,yes,10
cc,3,12
dd,4,13
这是我的perl代码
use strict;
use Getopt::Std;
my $input_file = $ARGV[0];
my @data = read_data_from_csv($input_file);
sub read_data_from_csv
{
my ($fh) = @_;
my @d = ();
open(FH,"<$fh") || die "Error: no open for $fh: $!";
while (<FH>) {
chomp;
my @list =split(/,/);
my ($aa) = $list[0];
my ($bb) = $list[1];
my ($cc) = $list[4];
push (@d,($aa,$bb,$cc));
}
close (FH);
return @d
}
print "@data\n";
cat test.csv
aa,13
/pkg/qct/software/perl/5.20.0/bin/perl test.pl test.csv
dd yes 13
解决方法
您所发布的代码有效:
use strict;
use Getopt::Std;
my $input_file = $ARGV[0];
my @data = read_data_from_csv($input_file);
sub read_data_from_csv {
my ($fh) = @_;
my @d = ();
#open(FH,"<$fh") || die "Error: no open for $fh: $!";
while (<DATA>) {
chomp;
my @list = split(/,/);
my ($aa) = $list[0];
my ($bb) = $list[1];
my ($cc) = $list[4];
push( @d,( $aa,$bb,$cc ) );
}
close(FH);
return @d;
}
print "@data\n";
__DATA__
aa,1,no,ed,8
bb,2,yes,10
cc,3,12
dd,4,13
输出:
aa 1 8 bb 2 10 cc 3 12 dd 4 13
我建议您需要检查您的输入文件-如果在Unix上,请尝试cat -v
,该可能显示您的行尾有错误。
如果您确实有此问题(或对其进行测试),则可以轻松解决:
s/[\r\n]//g;
更一般地说,尽管我认为您的代码中存在一些错误-例如“推”,可能没有按照您的想法去做,因为您正在将CSV压缩为平面数组。
我还建议使用Data::Dumper
测试输出,因为这很清楚发生了什么事情:
$VAR1 = [
' aa ','1 ','8 ',' bb ','2 ','10',' cc ','3 ','12','dd ','4 ','13'
];
您可以看到,根据push
中的内容,您已经弄平了数据,我假设不是您想要的。
因此,您可能要考虑使用[]
,因为这样您会得到:
$VAR1 = [
[
' aa ','8 '
],[
' bb ','10'
],[
' cc ','12'
],[
'dd ','13'
]
];
您也可以直接分配数组切片,而不是使用1-1:
push ( @d,[ @list[0,4] ] );
最后一点-使用单字母变量是一种不好的风格,您也应该use warnings;
。
给你
use strict;
use Getopt::Std;
use warnings;
use Data::Dumper;
my $input_file = $ARGV[0];
my @data = read_data_from_csv($input_file);
sub read_data_from_csv {
my ($fh) = @_;
my @d = ();
##NB Commented out so I can use inline data
#open(FH,"<$fh") || die "Error: no open for $fh: $!";
while (<DATA>) {
chomp;
s/[\r\n]//g;
my @list = split(/,/);
push( @d,4] ]);
}
##close(FH);
return @d;
}
print Dumper \@data;
__DATA__
aa,13
您可能要考虑的是,不是打开$ARGV[0]
中指定的文件,这恰恰是“魔术”文件句柄<>
的作用。它会打开在命令行上指定的文件并对其进行迭代,但是它还允许您“通过管道”进入STDIN
上的进程:
制作程序:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
## flattened array
my @data_A = map { s/[\r\n]//g; ( split(/,/) ) [0,4] } <>;
## preserving structure
my @data_B = map { s/[\r\n]//g; [( split(/,4]] } <>;
print Dumper \@data_B;
我很高兴您的代码可以减轻核心问题,但是我只是想说明简化选项。
,您可以使用https://metacpan.org/pod/Text::CSV_XS模块。 Text :: CSV_XS-逗号分隔值操作例程。您可以根据需要使用功能。
use strict;
use warnings;
use Text::CSV_XS;
use Data::Dumper qw(Dumper);
my @rows;
my @column_numbers = (0,4);
my $csv_file = "tst.csv";
# check https://metacpan.org/pod/Text::CSV_XS#binary
# check http://metacpan.org/pod/Text::CSV_XS#auto_diag
my $csv = Text::CSV_XS->new ({ binary => 1,auto_diag => 1 });
open my $fh,"<:encoding(utf8)",$csv_file or die "$csv_file: $!";
# $csv->getline_all ($fh); will return a reference to a list of getline ($fh) results.
#The map function of Perl provides a simple way to transform a list of values to another list of values.
@rows = map { [ @{ $_ }[@column_numbers] ] } @{ $csv->getline_all($fh) };
print Dumper(\@rows);
close $fh;
输出
$VAR1 = [
[
'aa ',[
'bb ',[
'cc ','13'
]
];
注意:请检查@ikegami Unable to read multiple columns from a .csv using Text::CSV_XS in Perl
提供的解决方案
地图:1)https://perldoc.perl.org/functions/map.html 2)https://perlmaven.com/transforming-a-perl-array-using-map
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。