Question

I will like to know how can I clone an extended class of SplHeap that contains objects. For example, if FooHeap extends SplHeap, is it possible for FooHeap to have a __clone method and clone its object elements?

class FooHeap extends SplHeap{
    public function compare($value1, $value2){.... }

    public function __clone(){

        // how do I access its elements to clone?
    }
}

Alternatively, if I have to create a new FooHeap object and re-insert the clones of the object elements, is there a way (e.g. from top to bottom, or from bottom to top) that I should re-insert the cloned elements to ensure optimized performance?

Was it helpful?

Solution

The essence of SplHeap is that it automatically sorts all inserted values (like objects), and when iterating over it, every value is deleted from the heap.

When you clone a heap, the inserted values are copied as well, but objects are not cloned, but copied as reference as expected.

The usual approach would be to iterate over the stored data and clone every object found. But because iterating deletes the nodes, you have to collect them somewhere and re-insert.

There is no choice in order, because all you can do is "get the next".

If you do worry about performance, measure!

I found this code to be working:

class MyHeap extends SplHeap
{

    public function compare($a, $b)
    {
        return (strcmp(get_class($a), get_class($b)));
    }

    public function __clone()
    {
        echo "Im cloning in ";
        foreach ($this as $obj) {
            $clones[] = clone($obj);
        }
        foreach ($clones as $obj) {
            $this->insert($obj);
        }
        var_dump($this);
    }
}

$heap = new MyHeap();

$obj1 = new stdClass();
$heap->insert($obj1);
$obj2 = new stdClass();
$heap->insert($obj2);

var_dump($heap);

$clone = clone($heap);

var_dump($clone);
foreach ($clone as $insert) {
    var_dump($insert);
}
foreach ($heap as $insert) {
    var_dump($insert);
}

Outputs:

class MyHeap#1 (0) {
}
Im cloning in class MyHeap#4 (0) {
}
class MyHeap#4 (0) {
}
class stdClass#6 (0) {
}
class stdClass#7 (0) {
}
class stdClass#2 (0) {
}
class stdClass#3 (0) {
}

OTHER TIPS

By defining a function __clone you can specify what variables you want to change for a cloned object. In the next example I set $cloned to true. The original object has $clone = false, but the cloned one has $cloned = true. Therefore $data remains unchanged.

<?php

class FooHeap extends SplHeap {
    public $data = "asd"  ;
    private $cloned = false ;

    public function __clone(){
          $this->cloned = true ;
        $this->rewind() ; //Just rewind iterator back to start, if you need
    }

    public function compare(){

    }
}

$original = new FooHeap() ;
$original->insert("some stuff") ;
$original->insert(100) ;

$clone = clone $original  ; //Data nodes are cloned from original object

$data = array() ;
$length = $clone->count() ;

for ($i = 0 ; $i < $length ; $i++){
    $data[] = $clone->current() ; //Access current data node and store it in data
    $clone->next() ;                // Move to the next data node
}

var_dump($data) ; //Check your data array

?>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top