PHP数组比较算法

时间:2012-01-08 22:00:10

标签: php arrays

在尝试模拟一些PHP行为时,我偶然发现了这个:

    $a=array(0 => 1, 'test' => 2);
    $b=array('test' => 3, 0 => 1);
    var_dump($a==$b, $a>$b, $b>$a);

根据var_dump $b的输出大于$a。在PHP手册中有一个Transcription of standard array comparison,它表明数组的值是逐个比较的,如果第二个数组中缺少第一个数组的键,则数组是无法比较的。到现在为止还挺好。但是,如果我尝试这个(仅改变$a的第一个元素):

    $a=array(0 => 2, 'test' => 2);
    $b=array('test' => 3, 0 => 1);
    var_dump($a==$b, $a>$b, $b>$a);

所有三个比较结果均为false。对我来说这看起来像“无法比拟”(因为>结果与<结果相同,而数组也不是==,这没有意义)但这不是适合PHP手册的转录。这两个键都存在于两个数组中,我希望此次$a更大,因为键{0的内容在$a中更大(2对1)。

我试图深入研究PHP源代码,并在zend_hash.c中找到了zend_hash_compare(),但其中的代码似乎与手册中描述的一样。

这里发生了什么?

3 个答案:

答案 0 :(得分:6)

编辑:正如约阿希姆所示,它处理了所谓的订单。窃取他的话: “$ a&gt; $ b在b上循环并首先找到'test'。'test'在$ b中更大,所以$ b更大并返回false。$ b&gt; $ a循环a并首先找到'0'。 0'在$ a中更大,所以$ a更大,它返回false。“

- 原帖 -

我不是百分百肯定我是对的;我之前没有见过这个,并且只是简单地研究了一下(顺便说一下,在一个很好的问题上,主要的荣誉!)。无论如何,看起来PHP文档是错误的,或者这是一个错误(在这种情况下你可能想提交它),这就是原因:

zend_hash_compare()的{​​{1}}中的

,似乎对zend_hash.c的内容存在一些疑惑(我正在查看第ordered行和1514 ,这是我最好的猜测是问题所在,没有做大量的测试)。

这就是我的意思;试试这个:

1552-1561

注意我只是切换了索引的顺序$a=array(0 => 2, 'test' => 2); $b=array(0 => 1, 'test' => 3); var_dump($a==$b, $a>$b, $b>$a); 返回$a>$b。另见:

true

此处请注意,$x=array(0 => 2, 'test' => 2); $y = $x; $y[0] = 1; $y['test'] = 3; var_dump($x==$y, $x>$y, $y>$x); 返回true。换句话说,PHP 只是匹配数组键!它关心数组中这些键的顺序!您可以通过提出“基础”数组并在修改之前将其“复制”到新变量(在我的x / y示例中)来防止这种情况,或者如果您愿意,可以创建一个对象。

换句话说,更简单地说,似乎PHP不只是查看键值,而是键值和键顺序

同样,我强调我不知道这种预期的行为(它似乎是他们应该在PHP手册中注意到的东西),或者是错误/错误/等(这似乎对我来说更有可能) )。但无论哪种方式,我发现它首先按键数($x>$y中的行1496-1501)进行比较,然后按键值和键顺序进行比较。

答案 1 :(得分:5)

似乎比较循环是在&gt;的情况下。在右手阵列上完成并且在&lt;在左手阵列上完成,即总是在所谓的“较小”阵列上。元素的顺序很重要,因为转录代码中的foreach循环遵循数组顺序。

换句话说;

$ a&gt; $ b遍历b并首先找到'test'。 'test'在$ b中更大,所以$ b更大,它返回false。

$ b&gt; $ a循环a并首先找到'0'。 “$”在$ a中更大,因此$ a更大,并返回false。

这实际上是有意义的,然后允许“更大”的数组包含“较小”数组不包含的元素,并且只要所有公共元素都更大,它们仍然更大。

答案 2 :(得分:-1)

我认为这里是逐一比较$a[0]>$b[0]$a['test']<$b['test']。 你不能说哪个数组更大。