在' while'下添加值到标量列表。环

时间:2014-04-07 14:08:52

标签: perl csv

当有人从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);

这确实有效并将其放在一个列表中,但不是按值计算,而是将所有值合并为一个。

4 个答案:

答案 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;