我有一个我要排序的数组数组.数组A的每个元素是一个包含3个元素的数组.数组A看起来像:
my @A = ([2,3,1], [1,2,3], [1,0,2], [3,1,2], [2,2,4]);
Run Code Online (Sandbox Code Playgroud)
我想按升序排序A. 比较2个元素时,使用第一个数字.如果存在平局,则使用第二个数字,然后使用第三个数字.
这是我的代码.我使用函数'cmpfunc'来比较2个元素.
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";
}
Run Code Online (Sandbox Code Playgroud)
结果:
1,2,3
1,0,2
2,3,1
2,2,4
3,1,2
Run Code Online (Sandbox Code Playgroud)
结果有些分类,但不正确.我的期望是:
1,0,2
1,2,3
2,2,4
2,3,1
3,1,2
Run Code Online (Sandbox Code Playgroud)
我的比较函数有错误吗?奇怪的是,当我将比较代码放入块中时,结果被正确排序.
my @C = sort { ($a->[0] <=> $b->[0]) or
($a->[1] <=> $b->[1]) or
($a->[2] <=> $b->[2]) } @A;
Run Code Online (Sandbox Code Playgroud)
tad*_*dmc 22
你正在执行
return ($a->[0] <=> $b->[0])
Run Code Online (Sandbox Code Playgroud)
它在到达任何"或"子句之前返回.
删除"return"关键字,或在整个 arg列表周围添加括号以便返回:
sub cmpfunc {
return(($a->[0] <=> $b->[0]) or
($a->[1] <=> $b->[1]) or
($a->[2] <=> $b->[2]));
}
Run Code Online (Sandbox Code Playgroud)
您观察到这种"错误"行为的原因是or操作员的优先级,尽可能低.在这种情况下,这意味着
return ($a->[0] <=> $b->[0]) or
($a->[1] <=> $b->[1]) or
($a->[2] <=> $b->[2]);
Run Code Online (Sandbox Code Playgroud)
被解释为OR-ing
return ($a->[0] <=> $b->[0])
Run Code Online (Sandbox Code Playgroud)
和其余的一行 - 在这种情况下是废话,因为回报永远不会回来.:)
所以你应该使用C的OR:
return ($a->[0] <=> $b->[0]) ||
($a->[1] <=> $b->[1]) ||
($a->[2] <=> $b->[2]);
Run Code Online (Sandbox Code Playgroud)
需要更多括号:
sub cmpfunc {
return (($a->[0] <=> $b->[0]) or
($a->[1] <=> $b->[1]) or
($a->[2] <=> $b->[2]));
}
Run Code Online (Sandbox Code Playgroud)
小智 5
sub cmpfunc {
return ($a->[0] <=> $b->[0]) or
($a->[1] <=> $b->[1]) or
($a->[2] <=> $b->[2]);
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处删除“返回”。
sub cmpfunc {
($a->[0] <=> $b->[0]) or
($a->[1] <=> $b->[1]) or
($a->[2] <=> $b->[2]);
}
Run Code Online (Sandbox Code Playgroud)