Arrays 我能';似乎无法正确地取消对数组的引用
我不太擅长Perl,但我需要能够对多维数组进行排序。我一直在玩一些测试代码,试图更好地掌握这个概念,我想我正在接近,但我找不到神奇的组合 我似乎不能做的是取消对数组的引用并使它们正确打印。除了被引用的数组中的值之外,我似乎可以得到关于这些引用的所有我需要知道的东西 我从一个以制表符分隔的平面文件中获取数据,因此在我的示例代码中,我通过拆分创建多个数组,然后将它们推入单个数组来模拟这种情况。实际上,我将在文件中循环,在选项卡上拆分,并在执行时将它们推入数组 如果有更好的办法,我洗耳恭听。平面文件中的每一行都是一条记录。我需要首先按日期排序,将最旧的记录排在最前面,然后再按账号对记录进行二次排序。我在网上看过几个例子,但没有发现任何与我需要模仿的数据相关的东西Arrays 我能';似乎无法正确地取消对数组的引用,arrays,perl,dereference,Arrays,Perl,Dereference,我不太擅长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 "@array\n";
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代码>位于程序顶部。这将及早发现许多错误
foreach
循环中的最后一行是正确取消引用$thingy
的行。但是,由于您已将@{$thingy}
放在
(字符串连接)操作符的左侧,因此数组处于标量上下文中,标量上下文中的数组根据其大小进行计算。只要说:
print "@{$thingy}\n";
要获取用空格分隔的@$thingy
元素,请执行以下操作:
print join('|', @{$thingy}), "\n";
如果要使用另一个分隔符,如竖线字符。你也可以说
print @{$thingy}, "\n";
不使用任何分隔符打印元素。@thingy
未声明且未定义(且不必要)
使用两个嵌套循环
使用数组引用在数组上迭代
然后在每个循环中迭代引用数组中的项
像这样
foreach my $array_ref (@sorted)
{
foreach my $item (@{$array_ref}) {
print $item, ",";
}
print "\n";
}
表达式@{$array\u 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 @sorted = sort { $a->[0] cmp $b->[0]
||
$a->[1] cmp $b->[1]
} @array;
push @array, [ split(/:/, 'X:Y:Z') ];
push @array, [ split(/:/, 'A:B:C') ];
...
您需要做的第一件事是将以下内容添加到脚本中:
use strict;
use warnings;
然后您将得到警告:
Global symbol "@thingy" requires explicit package name
这意味着未定义@thingy
。在perl中,$thingy
和@thingy
作为单独的变量计算
创建数组的另一种方法是使用匿名数组,如下所示:
my @sorted = sort { $a->[0] cmp $b->[0]
||
$a->[1] cmp $b->[1]
} @array;
push @array, [ split(/:/, 'X:Y:Z') ];
push @array, [ split(/:/, 'A:B:C') ];
...
这样就不必创建一次性变量。或者使用您描述的文件(\t
是选项卡):
与你的问题没有直接关系,但你可能想考虑这样的事情:<代码>我@数组=地图[Studio//],QW(X:Y:Z:B:C Q:L:P:0 U:E:G)< /代码>。这正是我所需要的。有时,我很难决定Perl是否有趣。这是我见过的最疯狂的细微差别。我从来没有想到这是我的问题。非常感谢。正如我在最初的帖子中所说,这只是一个测试脚本,我在尝试将代码插入主脚本之前一直在使用它。因此,所有的数组和推送都将在实际脚本中得到更好的处理。为了模拟我的情况,我只是加入了一些不好的东西,为了清晰起见,我在代码片段中加入了代码。但是我也要感谢主/次排序代码。在我的搜索中,我还没有在任何地方看到这一点,我只是想让这类东西发挥作用。这将是我的下一个挑战,但你让我轻松了。我已经测试过了,效果很好!
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;
for my $ref (@array) {
my $i = 0;
for my $value (@$ref) {
print $value;
print "," if ($i++ < $#$ref); # comma delimited
}
print "\n"; # end of record
}