icecave/parity

一个可定制的深度比较库。

3.0.1 2021-02-04 05:51 UTC

This package is auto-updated.

Last update: 2024-09-04 13:33:00 UTC


README

Build Status Code Coverage Latest Version

Parity 是一个用于 PHP 的深度比较库。

composer require icecave/parity

原因

PHP 无法提供一种可靠且严格地比较不同类型值的方法。大多数内置比较运算符经常会进行不希望的 类型转换。一个例外是 严格相等运算符,它有一个进一步的缺点,即它只能通过它们的身份来比较对象。没有提供类型严格机制来比较对象的属性;也没有提供相对比较运算符(小于、大于等)的类型严格版本。

Parity 通过提供以下功能的比较引擎来填补这一空白

  • 通过元素类型严格比较数组和对象
  • 递归安全的对象比较
  • 内置类型自然、类型严格的比较语义
  • 强大的机制,使类能够自定义比较行为

示例

可以通过 Parity 门面类的静态方法访问 Parity 比较引擎。这些方法接受任何类型,并保证产生一个确定性的比较结果1。以下是一些使用整数的简单示例。

use Icecave\Parity\Parity;

// The compare() method provides a strcmp-style comparison, and hence can be
// used as a sorting function for operations such as usort()
assert(Parity::compare(1, 2) < 0);

// The following methods are convenience methods, implemented on top of compare().
assert(Parity::isEqualTo(1, 2) === false);
assert(Parity::isNotEqualTo(1, 2) === true);
assert(Parity::isNotEqualTo(1, 2) === true);
assert(Parity::isLessThan(1, 2) === true);
assert(Parity::isLessThanOrEqualTo(1, 2) === true);
assert(Parity::isGreaterThan(1, 2) === false);
assert(Parity::isGreaterThanOrEqualTo(1, 2) === false);

概念

可比较的

Parity 的核心概念是 可比较的。任何提供其与其他值比较行为的对象都是可比较的。比较引擎支持以下可比较概念的细化

  • 受限可比较:可以查询其可以与之比较的值的可比较。
  • 自我可比较:只能与完全相同类型的其他对象进行比较的可比较。
  • 子类可比较:只能与同一类型或其派生类型的其他对象进行比较的可比较。
  • 任何可比较:可以自由地与任何其他类型的值进行比较的可比较。

比较器

一个 比较器 定义了除自身之外值的比较行为。 Parity 提供以下比较器实现

算法解决

Parity::compare($A, $B)使用以下过程来确定使用哪个比较算法

如果满足以下条件,则使用$A->compare($B)

  1. $A任何可比较的;或者
  2. $A受限制的可比较的,且$A->canCompare($B)返回true;或者
  3. $A自我可比较的,且$A$B是相同类型;或者
  4. $A子类可比较的,且$B$A->compare()实现的类的实例

如果上述条件都不满足,则尝试以相反的顺序进行比较,即将$A放在右边,将$B放在左边;结果也将被反转。如果仍然无法进行比较,Parity将回退到严格类型的深度比较。

在比较标量类型时,整数和双精度浮点数(PHP的唯一真实数值类型)被视为相同类型,因此表达式3 < 3.5 < 4是正确的。数字字符串不是以这种方式进行比较。

注意事项

  1. 比较递归对象不是真正确定性的操作,因为对象是通过它们的对象哈希进行比较的,而更深入的比较可能会导致无限递归。