在 PHP 中比较数组 - 有趣的行为
第一个示例:
$x = array("a" => 1, "b" => 2);
$y = array("b" => 1, "a" => 2);
$xLessY = ($x < $y);
$xGreaterY = ($x > $y);
var_dump($xLessY, $xGreaterY);
结果:$xLessY = true,$xGreaterY = true
第二个示例:
$x = array("a" => 2, "b" => 1);
$y = array("b" => 2, "a" => 1);
$xLessY = ($x < $y);
$xGreaterY = ($x > $y);
var_dump($xLessY, $xGreaterY);
结果:$ xLessY = false, $xGreaterY = false
根据 http://docs.php.net/manual/en/language.operators.comparison.php:
如果操作数 1 中的键未在以下位置找到 操作数 2 那么数组是 无法比较,否则 - 比较 按价值计算
存在于数组 $y 中,因此 $x 和 $y 是可比较的。 另请参阅文档中的示例:
// Arrays are compared like this with standard comparison operators
function standard_array_compare($op1, $op2)
{
if (count($op1) < count($op2)) {
return -1; // $op1 < $op2
} elseif (count($op1) > count($op2)) {
return 1; // $op1 > $op2
}
foreach ($op1 as $key => $val) {
if (!array_key_exists($key, $op2)) {
return null; // uncomparable
} elseif ($val < $op2[$key]) {
return -1;
} elseif ($val > $op2[$key]) {
return 1;
}
}
return 0; // $op1 == $op2
}
这种行为确实很奇怪:$x 小于 $y,同时 $x 大于 $y(第一个示例),并且两个数组是可比较的。
我认为这是因为 php 总是从符号“<”的一侧开始进行比较。我的意思是: for ($x < $y) php 将 $x 作为操作数 1,对于 ($x > $y) 它将 $y 作为操作数 1。尽管我在文档中没有找到有关此行为的任何内容。
您对此有何看法?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的假设是正确的。
>
运算符被解析为这基本上是说,
X > Y
相当于not X
Y
,当比较不可交换时,这当然是错误的。考虑在 bugs.php.net 上报告此问题。Your assumption is correct. The
>
operator is parsed asThis basically says,
X > Y
is equivalent tonot X < Y
, which is of course wrong when the comparison is not commutative. Consider reporting this on bugs.php.net.我不会说这个错误是在
$x > 中。 $y
被替换为$y
$x
。当然,如果你实现了
$x > $y
以参数在传递给比较函数时不交换位置的方式,您将解决这个特定问题。但你会得到另一个回报。现在你有:
因为第一个参数的第一个键总是首先比较,所以如果
reset($x)
reset($x)
reset($x)
reset($x)
reset($x)
reset($x)
reset($x)
$y[key($x)]
和reset($y)
$x[键($y)]
。但考虑另一种实现,它可以解决这个问题:
现在,当操作数的顺序固定时,
<
和>
是一致的,但是当我们交换操作数,因为我们仍然可以有cmp($x, $y) == -1
和cmp($y, $x) == -1
,这将意思是$x < $y
和$y < $x
都是 true。总之,唯一的解决方案是修复比较函数,使其行为是反对称的,即
cmp($x, $y) == - cmp($y, $x)
,至少在一组声称具有可比性的元素中。I wouldn't say the bug is in
$x > $y
being substituted for$y < $x
.Sure, if you implemented
$x > $y
in a way that the arguments did not exchange positions when passed to the comparison function, you would solve this particular problem. But you get another in return.Right now you have:
Because the first key of the first argument is always compared first, both conditions are true if
reset($x) < $y[key($x)]
andreset($y) < $x[key($y)]
.But consider another implementation, which would solve this problem:
Now
<
and>
are consistent when the order of the operands is fixed, but we now get weird behavior when we swap the operands because we could still havecmp($x, $y) == -1
andcmp($y, $x) == -1
, which would mean$x < $y
and$y < $x
would both be true.In sum, the only solution would be to fix the comparison function so that its behavior was antisymmetric, i.e. so that
cmp($x, $y) == - cmp($y, $x)
, at least within a set of elements that are claimed to be comparable.我可能是错的,但我认为你不能那样比较数组。我总是假设人们可以检查相等或不相等,但不能将数量与 << 进行比较。和>。
数组运算符的手册页似乎证实了这一点。
I may be wrong but I don't think you can compare arrays that way. I always assumed one can check for equality or inequality, but not compare quantities with < and >.
The man page on array operators seems to confirm this.