Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/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中对数组进行排序,但结果没有排序_Perl_Sorting - Fatal编程技术网

我想在Perl中对数组进行排序,但结果没有排序

我想在Perl中对数组进行排序,但结果没有排序,perl,sorting,Perl,Sorting,我有一个要排序的数组。数组A的每个元素都是一个包含3个元素的数组。 数组A看起来像: my @A = ([2,3,1], [1,2,3], [1,0,2], [3,1,2], [2,2,4]); 我想按升序对A排序。比较两个元素时,使用第一个数字。如果出现平局,则使用第二个数字,然后使用第三个数字 这是我的密码。我使用函数“cmpfunc”来比较两个元素 sub cmpfunc { return ($a->[0] <=> $b->[0]) or

我有一个要排序的数组。数组A的每个元素都是一个包含3个元素的数组。 数组A看起来像:

my @A = ([2,3,1], [1,2,3], [1,0,2], [3,1,2], [2,2,4]);
我想按升序对A排序。比较两个元素时,使用第一个数字。如果出现平局,则使用第二个数字,然后使用第三个数字

这是我的密码。我使用函数“cmpfunc”来比较两个元素

sub cmpfunc {
    return ($a->[0] <=> $b->[0]) or 
           ($a->[1] <=> $b->[1]) or
           ($a->[2] <=> $b->[2]);
}
my @B = sort cmpfunc @A;
print "Result:\n";
for my $element (@B) {
    print join(",", @{$element}) . "\n";
}
结果有些排序,但不正确。我所期望的是:

1,0,2
1,2,3
2,2,4
2,3,1
3,1,2
我的比较函数有错误吗? 奇怪的是,当我将比较代码放入块中时,结果被正确排序

my @C = sort { ($a->[0] <=> $b->[0]) or 
               ($a->[1] <=> $b->[1]) or
               ($a->[2] <=> $b->[2]) } @A;
my@C=sort{($a->[0]$b->[0])或
($a->[1]$b->[1])或
($a->[2]$b->[2])}@a;

需要更多的括号:

sub cmpfunc {
    return (($a->[0] <=> $b->[0]) or
            ($a->[1] <=> $b->[1]) or
            ($a->[2] <=> $b->[2]));
}
子cmpfunc{
返回($a->[0]$b->[0])或
($a->[1]$b->[1])或
($a->[2]$b->[2]);
}
您正在执行

return ($a->[0] <=> $b->[0])
返回($a->[0]$b->[0])
在到达任何“or”子句之前返回

删除“return”关键字,或在整个参数列表周围添加括号以返回:

sub cmpfunc {
    return(($a->[0] <=> $b->[0]) or
           ($a->[1] <=> $b->[1]) or
           ($a->[2] <=> $b->[2]));
}
子cmpfunc{
返回($a->[0]$b->[0])或
($a->[1]$b->[1])或
($a->[2]$b->[2]);
}

您观察到这种“错误”行为的原因是
运算符的优先级最低。在这种情况下,这意味着

return ($a->[0] <=> $b->[0]) or 
       ($a->[1] <=> $b->[1]) or
       ($a->[2] <=> $b->[2]);
返回($a->[0]$b->[0])或
($a->[1]$b->[1])或
($a->[2]$b->[2]);
被解释为或正在进行

return ($a->[0] <=> $b->[0])
返回($a->[0]$b->[0])
剩下的部分——在这种情况下是胡说八道,因为return永远不会回来

因此,您应该使用C或:

return ($a->[0] <=> $b->[0]) || 
       ($a->[1] <=> $b->[1]) ||
       ($a->[2] <=> $b->[2]);
return($a->[0]$b->[0])|
($a->[1]$b->[1])||
($a->[2]$b->[2]);
子cmpfunc{
返回($a->[0]$b->[0])或
($a->[1]$b->[1])或
($a->[2]$b->[2]);
}
您可以在此处删除“return”

    sub cmpfunc {
     ($a->[0] <=> $b->[0]) or 
     ($a->[1] <=> $b->[1]) or
     ($a->[2] <=> $b->[2]);
}
子cmpfunc{
($a->[0]$b->[0])或
($a->[1]$b->[1])或
($a->[2]$b->[2]);
}

丹尼尔的替代解决方案:

sub cmpfunc {
    return ($a->[0] <=> $b->[0]) ||
           ($a->[1] <=> $b->[1]) ||
           ($a->[2] <=> $b->[2]);
}
子cmpfunc{
返回($a->[0]$b->[0])||
($a->[1]$b->[1])||
($a->[2]$b->[2]);
}

这种情况下,
的问题是它的优先级低于赋值,因此您的函数只返回
($a->[0]$b->[0])
的结果,如果左手边的数值分别小于、等于或大于右手边,则返回值为-1、0或1<代码>| |
具有更高的优先级,因此在返回之前会对整个布尔表达式求值。如前所述,如果您喜欢将表达式括在括号中,而不是
|
。我个人不知道。

它仍然会返回第一个计算为true的语句。@Leonardoherra它应该这样做。实际上,它只返回第一个比较,不管返回什么。尝试
sub a{return 0 or die“Ough”}
。或使用更紧密的绑定或:
|
。相关:
    sub cmpfunc {
     ($a->[0] <=> $b->[0]) or 
     ($a->[1] <=> $b->[1]) or
     ($a->[2] <=> $b->[2]);
}
sub cmpfunc {
    return ($a->[0] <=> $b->[0]) ||
           ($a->[1] <=> $b->[1]) ||
           ($a->[2] <=> $b->[2]);
}