2011-10-03 17 views
2

這裏是C++/Python的人。比較兩個用戶定義對象的數組

我需要比較兩個php數組包含用戶定義的類。

class Point 
{ 
    var $x; 
    var $y; 

    function _construct($x_, $y_) 
    { 
    $this -> x = $x_; 
    $this -> y = $y_; 
    } 
} 

$mas1 = array(new Point(0,1),new Point(0,1),new Point(0,1)); 
$mas2 = array(new Point(0,1),new Point(0,1),new Point(0,1)); 

if (array_diff($mas1,$mas2) == array()) 
{ 
    echo "they're equal\n"; 
} 

我得到了「可捕捉的致命錯誤:類對象的Point不能轉換爲字符串」。當我試圖使用簡單

if ($mas1 == $mas2) 

我得到了錯誤。

問題:1)是否有方法爲我的類重載比較運算符2)如何正確比較兩個包含用戶定義類的數組?

謝謝。

我使用PHP 5.2.11

+4

你有8個問題,而不是一個單一的公認的答案。您需要回到舊的問題來解決這個問題,找到正確的答案並通過點擊複選標記來標記。 – Bojangles

+1

另外,它是'__construct'。 –

+0

當我這樣做,它說我需要15聲望才能做到這一點。我怎樣才能做到這一點? – fogbit

回答

1

我認爲你需要閱讀this

不幸的是,PHP不提供任何方式來編寫自己的比較方法,當您使用=====時會自動調用,但您可以通過方法調用(例如,

class comparableObject { 

    var $property1 = FALSE; 
    var $property2 = FALSE; 

    function looseCompare ($obj) { 
    if (!is_a($obj,'comparableObject')) return FALSE; 
    return $this->property1 == $obj->property1 && $this->property1 == $obj->property1; 
    } 
    function strictCompare ($obj) { 
    if (get_class($obj) !== 'comparableObject')) return FALSE; 
    return $this->property1 === $obj->property1 && $this->property1 === $obj->property1; 
    } 

} 

$a = new comparableObject; 
$b = new comparableObject; 
var_dump($a->looseCompare($b)); // TRUE 
var_dump($b->strictCompare($a)); // TRUE 

$a->property1 = ''; 
var_dump($a->looseCompare($b)); // TRUE (emtpy string == FALSE) 
var_dump($b->strictCompare($a)); // FALSE (emtpy string !== FALSE) 
+0

謝謝,我想讓比較變得簡單明瞭,但似乎我不得不通過我自己編寫比較函數。 – fogbit

2

目前,超載操作員的唯一方法是使用operator PECL extension。但是,對於array_diff()所有你需要做的就是定義__toString()從而使對象可以是compared as strings(見注)

class Point 
{ 
    var $x; 
    var $y; 

    function __construct($x_, $y_) 
    { 
     $this -> x = $x_; 
     $this -> y = $y_; 
    } 

    function __toString() 
    { 
     return "x:" . $this->x . " y:" . $this->y; 
    } 

} 

編輯:

如果你想比較兩個平等數組,array_diff()是錯誤的函數。你根本不需要任何超載或者toString();簡單地比較數組:

$mas1 = array(new Point(0,1),new Point(0,1),new Point(0,1)); 
$mas2 = array(new Point(0,1),new Point(0,1),new Point(0,1)); 
$mas3 = array(new Point(0,1),new Point(1,1),new Point(0,1)); 

if ($mas1 == $mas2) { 
    echo "MAS1 == MAS2\n"; 
} else { 
    echo "MAS1 != MAS2\n"; 
} 
if ($mas1 == $mas3) { 
    echo "MAS1 == MAS3\n"; 
} else { 
    echo "MAS1 != MAS3\n"; 
} 

輸出:

MAS1 == MAS2 
MAS1 != MAS3 
+0

我已經重載__toString()形成唯一的字符串表示,現在我有任何數組(具有不同的元素和大小)的比較結果「真」。無論如何,謝謝你的回答。 – fogbit

+0

確保你明白'array_diff()正在做什麼:它循環遍歷第一個數組的所有元素,並檢查它們是否存在於第二個數組中(以及任何其他數組傳入)。如果某個元素不存在於任何比較數組中,則返回該元素。 'array_diff()'不用於比較數組的相等性。 –

+0

@fogbit:如果你只是想看看兩個數組是否相等,則不需要任何重載。查看更新的答案。 –

5

事實上,PHP不支持重載運算符。第一個比較只測試字符串數組,而第二個比較測試對象的內部數字而不測試其內容。

你應該在這裏做的是使用函數array_udiff。

該函數允許您使用回調函數比較兩個數組。在這個回調函數中,你可以包含你想要的邏輯。該函數返回比較的兩個數組之間的差異數組。如果你想檢查兩者是否相等,看看返回的數組是否爲空。見array_udiff()

請參見下面的例子:

class Point 
{ 
    var $x; 
    var $y; 

    function _construct($x_, $y_) 
    { 
    $this -> x = $x_; 
    $this -> y = $y_; 
    } 

    static function compare(Point $a, Point $b) 
    { 
    // Do your logic here. 
    if ($a->x === $b->x && $a->x === $b->x) { 
     return 0; 
    } 
    return ($a->x > $b->x)? 1:-1; 
    } 
} 

$mas1 = array(new Point(0,1),new Point(0,1),new Point(0,1)); 
$mas2 = array(new Point(0,1),new Point(0,1),new Point(0,1)); 

if(count(array_udiff($mas1, $mas2, 'Point::compare')) == 0) { 
    // Eq 
} 
else { 
    // Diff 
} 
+0

這是我需要的。但問題是我有空數組,因爲在euqal和非等數組的情況下。 – fogbit

1

一個問題現在的問題是,事實上,你的陣列將永遠是平等的,因爲Point類定義是錯誤的。

PHP中的構造函數是__construct(兩個下劃線),與您所做的相反:_construct(單下劃線)。因此,您的構造函數永遠不會執行,並且$x$y永遠不會分配給您的對象實例。

如果你解決它:

class Point 
{ 
    var $x; 
    var $y; 

    function __construct($x_, $y_) 
    { 
    $this -> x = $x_; 
    $this -> y = $y_; 
    } 
} 

然後,你可以簡單地做:

$mas1 = array(new Point(0,1),new Point(0,1),new Point(0,1)); 
$mas2 = array(new Point(0,1),new Point(0,1),new Point(0,1)); 
$mas3 = array(new Point(0,1),new Point(0,1),new Point(0,2)); 
$mas4 = array(new Point(0,1),new Point(0,1),new Point(0,1),new Point(0,1)); 

var_dump($mas1 == $mas2); // true 
var_dump($mas2 == $mas3); // false 
var_dump($mas2 == $mas4); // false