PHP中对象的差异集合

时间:2010-07-07 19:39:08

标签: php design-patterns

我经常遇到一个场景,我有两个对象集合(数组或IteratorAggregate类),需要区分两个列表。

差异,我的意思是:

  • 检测重复的对象(检测重复的逻辑会因具体情况而异)
  • 添加新对象
  • 删除不在其他列表中的对象

基本上,我正在寻找与对象一起使用的array_diff之类的东西。到目前为止,我一直在为每种类型的集合反复编写相同的逻辑。显然,由于重复对象的条件因情况而异,因此没有单一的解决方案。但是,人们发现有一种共同的模式或抽象方式可以解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

spl_object_hash将帮助您确定两个对象是否相同。

答案 1 :(得分:1)

自PHP5.2起,存在一个带有SplObjectStorage的本地Object集合:

  

SplObjectStorage类提供从对象到数据的映射,或者通过忽略数据来提供对象集。在涉及唯一标识对象的需要的许多情况下,这种双重目的可能是有用的。

示例

$obj1 = new StdClass; $obj1->prop = 1;
$obj2 = new StdClass; $obj2->prop = 2;
$obj3 = new StdClass; $obj3->prop = 3;
$obj4 = new StdClass; $obj4->prop = 4;
$obj5 = new StdClass; $obj5->prop = 5;

$collection1 = new SplObjectStorage;
$collection1->attach($obj1);
$collection1->attach($obj2);
$collection1->attach($obj3);

$collection2 = new SplObjectStorage;
$collection2->attach($obj3);
$collection2->attach($obj4);
$collection2->attach($obj5);   

SplObjectStorage实现了Countable,Iterator,Traversable,Serializable和ArrayAccess(自5.3起),因此您可以像遍历任何其他Traversable一样轻松地迭代它。当SplObjectStorage用作对象集时,它不能在SplObjectStorage中出现两次。您可以使用以下函数轻松比较两个集合:

function collection_diff(SplObjectStorage $c1, SplObjectStorage $c2)
{
    $diff = new SplObjectStorage;
    foreach($c1 as $o) {
        if(!$c2->contains($o)) {
            $diff->attach($o);
        }
    }
    return $diff;
}

当然,您可以将其调整为使用自定义比较。用法很简单:

$diff = collection_diff($collection1, $collection2);
var_dump( $diff ); // will contain $obj1 and $obj2

进一步阅读: