我似乎无法正确取消引用数组



我不太擅长Perl,但我需要能够在多维数组上进行排序。我一直在玩一些测试代码,试图更好地掌握这个概念,我想我正在接近,但我找不到神奇的组合。

我似乎不能做的是取消引用我的数组并让它们正确打印。我似乎可以得到世界上我需要了解的有关这些引用的所有信息,除了被引用的数组中的值。

从制表符分隔的平面文件中获取数据,因此在我的示例代码中,我通过拆分创建多个数组,然后将它们推送到单个数组来模拟它。在实践中,我将遍历文件,在选项卡上拆分并将它们推入数组。

如果有更好的方法,我会全力以赴。平面文件中的每一行都是一条记录。我需要首先按日期排序以将最旧的记录放在顶部,然后进行二次排序以按帐户编号对记录进行分组。我在网上看了几个例子,但没有找到任何似乎适用于我需要模仿的数据的东西。

my @s1 = split(/:/, 'X:Y:Z');
my @s2 = split(/:/, 'A:B:C');
my @s3 = split(/:/, 'Q:L:P:0');
my @s4 = split(/:/, 'U:E:G');
my @array = ();
push(@array, @s1);
push(@array, @s2);
push(@array, @s3);
push(@array, @s4);
print "@arrayn";
my @sorted = sort { $a->[0] cmp $b->[0] } @array;
print "n";
foreach $thingy (@sorted)
{
    print @thingy . "n"; #result: number 0
    print $thingy . "n"; #result: reference
    #print ${$thingy} . "n"; #result: 'Not a scalar reference' error
    print ${@thingy} . "n"; #result: file name (???)
    print @{$thingy} . "n"; #result: length of the array referenced
}

首先,您应该始终将use strict;放在程序的顶部。 这将及早发现许多错误。

foreach循环中的最后一行是正确取消引用$thingy的行。 但是,由于您已将@{$thingy}放在 .(字符串串联)运算符的左侧,因此数组位于标量上下文中,而标量上下文中的数组的计算值取决于其大小。 只需说:

print "@{$thingy}n";

获取@$thingy元素用空格分隔,或一般分隔

print join('|', @{$thingy}), "n";

如果要使用其他分隔符,如竖线字符。 你也可以说

print @{$thingy}, "n";

以打印完全不带分隔符的元素。

@thingy是未声明和未定义的(并且不必要的)。

使用两个嵌套循环来

  1. 使用数组引用遍历数组
  2. 然后在每个循环中迭代该引用数组中的项。

喜欢这个

foreach my $array_ref (@sorted)
{
    foreach my $item (@{$array_ref}) {
        print $item, ",";
    }
    print "n";
}

表达式@{$array_ref}将取消引用数组引用。然后像数组一样使用它。

加法:

您可以替换

my @s1 = split(/:/, 'X:Y:Z');
my @s2 = split(/:/, 'A:B:C');
my @s3 = split(/:/, 'Q:L:P:0');
my @s4 = split(/:/, 'U:E:G');
my @array = ();
push(@array, @s1);
push(@array, @s2);
push(@array, @s3);
push(@array, @s4);

my @array = ();
push(@array, map { [split(/:/, $_)] } qw(X:Y:Z A:B:C Q:L:P:0 U:E:G));

如果排序需要两个条件(第一个索引的主要条件和第二个索引的次要条件),则可以这样写:

my @sorted = sort { $a->[0] cmp $b->[0] 
                             ||
                    $a->[1] cmp $b->[1] 
                  } @array;

您需要做的第一件事是将其添加到脚本中:

use strict;
use warnings;

然后,您将收到警告:

Global symbol "@thingy" requires explicit package name

这意味着未定义@thingy。在 perl 中,$thingy@thingy 算作单独的变量。

创建数组的另一种方法是使用匿名数组,如下所示:

push @array, [ split(/:/, 'X:Y:Z') ];
push @array, [ split(/:/, 'A:B:C') ];
...

这样,您就不必创建一次性变量。或者使用类似您描述的文件(t是选项卡):

while (<>) {
    push @array, [ split /t/, $_ ];
}

一种从perlmonks对多列进行排序的方法:

my @a = ([1,2], [3,4]);
my @b = sort {
    $a->[0] <=> $b->[0] || # the result is -1,0,1 ...
    $a->[1] <=> $b->[1]    # so [1] when [0] is same
} @a;

http://www.perlmonks.org/index.pl?node_id=674374

当然,这假设您的字段中存在数值。否则使用 cmp .

要打印:

for my $ref (@array) {
    my $i = 0;
    for my $value (@$ref) {
        print $value; 
        print "," if ($i++ < $#$ref); # comma delimited
    }
    print "n"; # end of record
}

相关内容

  • 没有找到相关文章

最新更新