我想在Perl中对数组进行排序,但结果没有排序
我有一个要排序的数组。数组A的每个元素都是一个包含3个元素的数组。 数组A看起来像:我想在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
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]);
}