这是一个最佳实践问题。太空船操作员何时在排序之外使用?
我只看到了在数字排序例程中使用的Perl飞船运算符(< =>)。但在其他情况下似乎很有用。我只是想不出实际的用途。
任何人都可以给我一个什么时候可以在Perl排序之外使用的例子吗?
这是一个最佳实践问题。太空船操作员何时在排序之外使用?
我只看到了在数字排序例程中使用的Perl飞船运算符(< =>)。但在其他情况下似乎很有用。我只是想不出实际的用途。
任何人都可以给我一个什么时候可以在Perl排序之外使用的例子吗?
我正在写一个机器人乔的控制系统,想要去机器人玛丽和充电她。他们沿着线上的整数点移动。乔从$ j开始,每时间单位可以沿任何方向走1米。玛丽仍然站在$ m,不能移动 - 她需要一个很好的补给!该控制程序会看起来像:
while ($m != $j) {
$j += ($m <=> $j);
}
在任何类型的比较方法。例如,你可能有一个复杂的对象,但仍然有一个定义的“顺序”,所以你可以为它定义一个比较函数(你不需要在排序方法中使用,尽管它会很方便):
package Foo;
# ... other stuff...
# Note: this is a class function, not a method
sub cmp
{
my $object1 = shift;
my $object2 = shift;
my $compare1 = sprintf("%04d%04d%04d", $object1->{field1}, $object1->{field2}, $object1->{field3});
my $compare2 = sprintf("%04d%04d%04d", $object2->{field1}, $object2->{field2}, $object2->{field3});
return $compare1 <=> $compare2;
}
这当然是一个完全人为的例子。但是,在我公司的源代码中,我发现几乎与上述内容相同,用于比较用于保存日期和时间信息的对象。
另外一个使用我能想到的是用于统计分析 - 如果一个值与值列表重复运行,你可以告诉如果该值大于设定的算术平均高或低:
use List::Util qw(sum);
# $result will be
# -1 if value is lower than the median of @setOfValues,
# 1 if value is higher than the median of @setOfValues,
# 0 if value is equal to the median
my $result = sum(map { $value <=> $_ } @setOfValues);
这里还有一个,从wikipedia:“如果两个参数不能比较(例如其中一个是NaN),操作符返回undef。”即你可以一次确定两个数字是否是一个数字,尽管个人而言我会选择不太神秘的Scalar::Util :: looks_like_number。
实际上,'undef'行为会导致问题,因为'undef'会导致Perl很可能死亡。但是我们可以做一个处理NaN的数字排序:'sub numeric {$ a <=> $ b //($ a == $ a) - ($ b == $ b)}'这会将NaN排序到开头,具有至少不会死亡的积极效果。 – 2009-09-03 03:14:47
的<=>
运营商将是一个有用的binary search algorithm。大多数编程语言没有一个运算符进行三方比较,因此每次迭代需要进行两次比较。用<=>
你可以做一个。
sub binary_search {
my $value = shift;
my $array = shift;
my $low = 0;
my $high = $#$array;
while ($low <= $high) {
my $mid = $low + int(($high - $low)/2);
given ($array->[$mid] <=> $value) {
when (-1) { $low = $mid + 1 }
when (1) { $high = $mid - 1 }
when (0) { return $mid }
}
}
return;
}
鉴于如何正确执行二分查找是非常困难的,我只能希望我没有向世界贡献另一个破碎的例子。 :P – 2009-09-03 13:55:13
将这两个比较从明确写入的语句委派给预处理器的内部结构有什么性能优势? – 2009-09-03 15:38:15
在字节码级别有一个运算符,而不是两个:'perl -MO = Terse -e“$ a <=> $ b”'这就是说,由于Perl是用C实现的(它没有三路比较运算符) '<=>'必须作为内部的两个比较来实现。任何性能优势都是扩展发生在C而不是Perl中。当然,最终的限制是处理器的指令集支持的,而不管运营商C具有什么。 – 2009-09-03 17:26:40
@ether:只有“运营商”标签?我以为你喜欢创建新的操作员标签! – 2011-01-20 11:46:16