当有人从csv文件中读取值时,有人可以解释一下如何将值添加到标量列表中吗?
代码如下:
open (IN, $infile) || die "Cannot open $infile\n";
my ($x,$y);
while (my $line = <IN>){
chomp ($line);
my @temp = split (/,/,$line);
$x .= $temp[0].",";
$y .= $temp[1].",";
}
$x = [$x];
$y = [$y];
close (IN);
这确实有效并将其放在一个列表中,但不是按值计算,而是将所有值合并为一个。
答案 0 :(得分:3)
你说“列表”,但你的意思是“数组”。如果你从实际使用数组开始会有所帮助!
my (@xs, @ys);
while (my $line = <IN>){
chomp ($line);
my ($x, $y) = split (/,/,$line);
push @xs, $x;
push @ys, $y;
}
my $xs = \@xs;
my $ys = \@ys;
答案 1 :(得分:3)
略微优雅;并不要求用两个多余的变量来混淆你的命名空间。
my ($xs, $ys) = ([], []);
while(my $line = <IN>) { #Note: don't use bare filehandles like this. (See below)
chomp $line;
my ($x, $y) = split /,/, $line;
push @$xs, $x;
push @$ys, $y;
}
#done
裸露的文件句柄是个坏主意。使用词法文件句柄。 (并且3-arg打开!)。 Lexical文件在超出范围时会自动关闭。请参阅perlopentut。
open FH, '<', $file or die "Can't open $file: $!\n"; #Bad
open my $fh, '<', $file or die "Can't open $file: $!\n"; #Better
答案 2 :(得分:2)
自Merijn Brand(又名Tux)最新发布的Text::CSV_XS
以来,它确实允许使用RFC7111中指定的 text / csv片段标识符。这使得获取csv文件的特定片段变得非常简单。
此代码现在非常简单:
use strict;
use warnings;
use Text::CSV_XS ('csv');
my $infile = 'foobar.csv';
my @column_1 = map {$_->[0]} @{ csv(in => $infile, fragment => 'col=1') };
my @column_2 = map {$_->[0]} @{ csv(in => $infile, fragment => 'col=2') };
csv
函数返回对array_of_arrays的引用。因此,@{…}
运算符需要解除引用map
。
csv
函数(对于那些不想做OOP的函数)需要多个参数:
in =&gt;
指定输入,在本例中为输入文件。无需进行所有花哨的检查或使用文件句柄。所有人都在照顾。
fragment =&gt;
这可以从以下选择器中选择一个:&#39; row&#39;,&#39; col&#39;或者&#39; cell&#39;和范围。
行= 1; 5-7; 10 - *
表示:第1行,第5行至第7行,最后从10直到结束
COL = 2; 8-12
表示:第2列,第8列至第12列
细胞= 3,4-8,15
从12行和6列返回一个块,从单元格3,4开始(第3列,第4行)。
警告:在解析csv文件时,不要试图依靠自己的聪明,很多时候人们会陷入陷阱,只会意识到某些列突然包含逗号自己。
答案 3 :(得分:1)
虽然Theo的答案非常完美,但它仍然会读取文件两次
使用Spreadsheet :: Read(以及Text :: CSV_XS下面)更容易:
use Spreadsheet::Read;
my $ss = ReadData ("file.csv");
my @col1 = @{$ss->[1]{cell}[1]}; unshift @col1; # SS = 1-base [0] does not contain a cell
my @col2 = @{$ss->[1]{cell}[2]}; unshift @col2;
使用Text :: CSV_XS,但只读取一次文件
use Text::CSV_XS qw( csv );
my $col_1_2 = csv (in => "file.csv", fragment => "col=1;2");
my @column_1 = map {$_->[0]} @$col_1_2;
my @column_2 = map {$_->[1]} @$col_1_2;