簡體   English   中英

比較兩個用戶定義對象數組

[英]compare two arrays of user-defined objects

這里是C ++ / Python的人。

我需要比較兩個php-arrays containsig用戶定義的類。

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

實際上,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
}

目前,重載運算符的唯一方法是使用operator PECL擴展 但是,對於array_diff()您需要做的就是定義__toString()以便可以將對象作為字符串進行比較 (請參閱注釋)

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

我想你需要讀這個

不幸的是,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)

現在的一個問題是,實際上,你的數組總是相等的,因為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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM