代码之家  ›  专栏  ›  技术社区  ›  Bryan M.

PHP中对象的不同集合

  •  3
  • Bryan M.  · 技术社区  · 14 年前

    我经常遇到这样一个场景:我有两个对象集合(数组或迭代器聚合类),需要对这两个列表进行区分。

    我指的是diff:

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

    基本上,我在找 array_diff 与对象一起工作。到目前为止,我一直在为每种类型的集合反复编写相同的逻辑。显然,由于复制对象的条件会因情况不同而不同,因此没有一个奇异解。但是有没有一个共同的模式或抽象,人们发现是一个优雅的方式来处理这个?

    2 回复  |  直到 14 年前
        1
  •  2
  •   John Conde    14 年前

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

        2
  •  1
  •   Gordon Haim Evgi    14 年前

    由于php5.2,有一个本机对象集合 SplObjectStorage :

    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开始),因此您可以像迭代任何其他可遍历的一样轻松地对其进行迭代。同一对象用作对象集时,不能在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
    

    进一步阅读: