比较两个用户定义对象的数组

发布于 2024-12-08 01:16:00 字数 620 浏览 2 评论 0原文

这里是 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 类的对象无法转换为字符串”。当我尝试使用 simple 时,

if ($mas1 == $mas2)

我得到了 False。

问题: 1)有没有办法为我的类重载比较运算符 2)如何正确比较包含用户定义类的两个数组?

谢谢。

我使用 php 5.2.11

C++/Python guy here.

I need to compare two php-arrays containig user-defined classes.

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";
}

i got "Catchable fatal error: Object of class Point could not be converted to string". When i tried to use simple

if ($mas1 == $mas2)

i got False.

Questions: 1) is there way to overload comparison operator for my class Point 2) how to compare two arrays containing user-defined classes correctly?

Thank you.

I use php 5.2.11

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

暗藏城府 2024-12-15 01:16:00

事实上,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
}

In fact, PHP doesn't support overloaded operators. The first comparison tests only array of strings, while the second tests the internal number of the object and not its content.

What you should do here is use the function array_udiff.

This function allows you to compare two arrays using a callback function. In this callback function you can include the logical you want. This function returns an array of differences between the two arrays compared. If you want to check if both are equal, see if the returned array is empty. See array_udiff()

See the example below:

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
}
绾颜 2024-12-15 01:16:00

目前重载运算符的唯一方法是使用 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

Currently the only way to overload operators is to use the operator PECL extension. But, for array_diff() all you need to do is define __toString() so that the objects can be compared as strings (see notes):

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;
   }

}

Edit:

If you are trying to compare equality of two arrays, array_diff() is the wrong function. You don't need any overloading or toString() at all; simply compare the arrays:

$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";
}

Output:

MAS1 == MAS2
MAS1 != MAS3
撩起发的微风 2024-12-15 01:16:00

我认为您需要阅读

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

I think you need to read this.

Unfortunately, PHP does not provide any way to write your own comparison method that will be automatically invoked when you use == or === but you could just do it with a method call, e.g.

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)
泪痕残 2024-12-15 01:16:00

现在的一个问题是,事实上,您的数组将始终相等,因为 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

One problem right now is that, in fact, your arrays will always be equal because the Point class definition is wrong.

A constructor in PHP is __construct (two underscores), as opposed to what you did: _construct (single underscore). Therefore, your constructor is never executed, and $x and $y are never assigned to your object instance.

If you fix it:

class Point
{
  var $x;
  var $y;

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

Then you can simply do:

$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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文