Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 尝试从sub打印数组时,仅打印第一个元素_Perl_Subroutine - Fatal编程技术网

Perl 尝试从sub打印数组时,仅打印第一个元素

Perl 尝试从sub打印数组时,仅打印第一个元素,perl,subroutine,Perl,Subroutine,我正在编写一个Perl脚本,它要求我从文件中取出一整列并对其进行操作。例如,取出列A并将其与另一个文件中的另一列进行比较 A B C A B C A B C 到目前为止,我已经: sub routine1 { ( $_ = <FILE> ) { next if $. < 2; # to skip header of file my @array1 = split(/\t/, $_); my $file1

我正在编写一个Perl脚本,它要求我从文件中取出一整列并对其进行操作。例如,取出列A并将其与另一个文件中的另一列进行比较

A B C

A B C

A B C
到目前为止,我已经:

sub routine1
{
    ( $_ = <FILE> )

    {
        next if $. < 2; # to skip header of file

        my @array1 = split(/\t/, $_);
        my $file1 = $array1[@_];

        return $file1;
    }
}
子例程1
{
( $_ =  )
{
下一步如果$.<2;#跳过文件头
my@array1=拆分(/\t/,$);
我的$file1=$array1[@_];
返回$file1;
}
}

我大部分都做完了。唯一的问题是,当我调用打印子例程时,它只打印数组中的第一个元素(即,它只打印一个A)。

尝试用以下内容替换大部分子例程:

 my @aColumn = ();
 while (<FILE>) 
 {
    chomp;
    ($Acol, $Bcol, $Ccol) = split("\t");
    push(@aColumn, $Acol);
  }
  return @aColumn
my@aColumn=();
而()
{
咀嚼;
($Acol、$Bcol、$Ccol)=拆分(“\t”);
推送(@aColumn,$Acol);
}
返回@aColumn

跳到最后,下面将拉出文件中的第一列
blah.txt
,并将其放入一个数组中供您稍后操作:

use strict;
use warnings;
use autodie;

my $file = 'blah.txt';

open my $fh, '<', $file;

my @firstcol;

while (<$fh>) {
    chomp;
    my @cols = split;
    push @firstcol, $cols[0];
}

use Data::Dump;
dd \@firstcol;
使用严格;
使用警告;
使用自动模具;
my$file='blah.txt';

打开我的$fh,“我确信你真正拥有的是这个

sub routine1
{
    while ( $_ = <FILE> )

    {
        next if $. < 2; # to skip header of file

        my @array1 = split(/\t/, $_);
        my $file1 = $array1[@_];

        return $file1;
    }
}
输出

B B

这里有几个项目要考虑的是,在编写一个从文件中获取列值数组的子程序解决方案时要考虑:

  • 在进入
    while
    循环之前跳过文件头,以避免对每个文件行进行行号比较
  • split
    通过使用
    split
    的限制,仅限所需的列数。这可以大大加快这一过程
  • 或者,使用文件名初始化Perl的
    @ARGV
    本地副本,并让Perl处理文件i/o
创建同时使用文件名和列号的子例程的解决方案非常好,因此它也在下面实现:

use strict;
use warnings;

my @colVals = getFileCol( 'File.txt', 0 );
print "@colVals\n";

sub getFileCol {
    local @ARGV = (shift);
    my ( $col, @arr ) = shift;

    <>;    # skip file header
    while (<>) {
        my $val = ( split ' ', $_, $col + 2 )[$col] or next;
        push @arr, $val;
    }

    return @arr;
}

希望这有帮助

您发布的代码无法编译。你确定你没有像while($\u=){…}
这样的东西吗?这很奇怪。它为我编译。不,我没有那种东西。上面的代码正是我所拥有的。您有什么版本的Perl?我目前使用的是Perl v.5.16.3。当我输入“print routine1(1)”时,只打印出一个A而不是整个列,我猜您在
($)
之后有一个分号,因为即使在Perl 5.16.3中,我在foo第10行的“{”附近也会出现
语法错误
使用
split
w/o显式参数时无需
chomp
,因为它会删除尾随的换行符。TY@Kenosis,我不知道。我可能仍然会选择用perl one liner以外的任何语言编写显式代码,因为我可以看到以后很容易引入错误。而且我在尝试教授n时肯定会使用它ew person如何编写代码,如本例所示。不过,请欣赏该技巧。非常欢迎您。当您与Perl新手一起工作时,您对显式使用
chomp
提出了非常好的观点。
use strict;
use warnings;

my @colVals = getFileCol( 'File.txt', 0 );
print "@colVals\n";

sub getFileCol {
    local @ARGV = (shift);
    my ( $col, @arr ) = shift;

    <>;    # skip file header
    while (<>) {
        my $val = ( split ' ', $_, $col + 2 )[$col] or next;
        push @arr, $val;
    }

    return @arr;
}
A A