2011-06-25 30 views
6

第一個例子:比較陣列 - 有趣的行爲

$x = array("a" => 1, "b" => 2); 
$y = array("b" => 1, "a" => 2); 
$xLessY = ($x < $y); 
$xGreaterY = ($x > $y); 
var_dump($xLessY, $xGreaterY); 

結果:$ xLessY = 真正,$ xGreaterY = 真正

第二個例子:

$x = array("a" => 2, "b" => 1); 
$y = array("b" => 2, "a" => 1); 
$xLessY = ($x < $y); 
$xGreaterY = ($x > $y); 
var_dump($xLessY, $xGreaterY); 

結果:$ xLessY = ,$ xGreaterY =

http://docs.php.net/manual/en/language.operators.comparison.php根據文檔:

如果從操作數1鑰匙沒有 操作數2,則發現陣列是 不可比否則, - 比較 按值計算

在我們的例子中,數組$ x中的每個鍵都存在於數組$ y中,所以$ x和$ y是comp耕地。 參見例如,從文檔:

// 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.儘管我在文檔中沒有找到有關此行爲的任何信息。
你對此有何看法?

+0

我懷疑你可能是正確的,無論哪個值在'<'的最尖端被用作第一個操作數。當然,如果你看看PHP源代碼,你可以找到答案... – 2011-06-25 20:42:51

回答

0

我可能是錯的,但我不認爲你可以用這種方式比較數組。我總是假定可以檢查平等或不平等,但不能將數量與<和>進行比較。

man page on array operators似乎證實了這一點。

+0

還有[另一個手冊頁](http://php.net/manual/en/language.operators.comparison.php) 。參見下表「與各種類型的比較」和下面的文本:「如果在操作數2中沒有找到操作數1的密鑰,那麼數組中的元素較少,否則 - 按值比較值(請參見以下示例)」 。還有我寫的example(standard_array_compare函數) – Andy

1

你的假設是正確的。該>操作被解析爲

| expr '>' expr { zend_do_binary_op(ZEND_IS_SMALLER, &$$, &$3, &$1 TSRMLS_CC); } 

這基本上說,X > Y相當於not X < Y,這當然是錯誤的,當比較是不可交換的。考慮在bugs.php.net上報告這一點。

+0

可交換? 'X> Y'是可交換的,意味着''X> Y''等價於'Y> X'。另外,你說「比較(比較btw)不可交換」暗示'X> Y'不等於'不是X Y'相當於'不是X $ y'和'$ y> $ x'對於' $ x!= $ y'。 – Artefacto

+0

我同意沒有明智的方法來排序關聯數組,但這並不意味着設置一些任意順序是沒有用的 - 例如,許多算法依賴於正在排序的數據。然而,目前的情況是,不僅在數組宇宙中沒有總順序,而且手工狀態下有明確定義的順序的數組在'<' and '>'之間實際上並不一致。 – Artefacto

1

我不會說這個bug是$x > $y$y < $x所取代。

當然,如果你實現了$x > $y這種方式,參數在傳遞給比較函數時沒有交換位置,你可以解決這個問題。但你得到另一個回報。

現在您有:

$x < $y <=> cmp($x, $y) == -1 
$x > $y <=> cmp($y, $x) == -1 

因爲第一個參數的第一密鑰總是首先比較,兩個條件都爲真,如果reset($x) < $y[key($x)]reset($y) < $x[key($y)]

但考慮另一種實現方式,這將解決這個問題:

$x < $y <=> cmp($x, $y) == -1 
$x > $y <=> cmp($x, $y) == +1 

現在<>當操作數的順序是固定的是一致的,但我們現在得到怪異的行爲,當我們交換操作數,因爲我們仍然可以有cmp($x, $y) == -1cmp($y, $x) == -1,這意味着$x < $y$y < $x都是正確的。

總而言之,唯一的解決方案是修正比較函數,使其行爲是反對稱的,即至少在聲稱可比的一組元素內。

+0

我認爲這種行爲'$ x <$ y == -1'和'$ y <$ x == -1'在無序數組的情況下更容易理解。這與文檔更加一致。 – Andy

+0

也許這不是一個錯誤,但他們應該記錄它 – Andy