Search code examples
phparraysarray-filter

PHP - Delete Item from Hash Table (array) using array_filter


In PHP, I know there is no official way to delete items once they have been put into an array. But there must be a "best-method" solution to my problem. I believe this may lie in the array_filter function.

Essentially, I have a shopping cart object that stores items in a hashtable. Imagine you can only ever buy one of any item at a time.

I do

add_item(1);
add_item(2);
remove_item(1);

get_count() still returns 2.

var $items;


function add_item($id) {
    $this->items[$id] = new myitem($id);
}

function remove_item($id) {
    if ($this->items[$id]) {
        $this->items[$id] = false;
        return true;
    } else {    
        return false;
    }
}


function get_count() {
    return count($this->items);
}

What do people think is the best method to use in get_count? I can't figure out the best way to use array_filter that simply doesn't return false values (without writing a seperate callback).

Thanks :)


Solution

  • No official way? Sure there is! Unset!

    <?php
    
    class foo
    {
        var $items = array();
    
    
        function add_item($id) {
                $this->items[$id] = new myitem($id);
        }
    
        function remove_item($id)
        {
            unset( $this->items[$id] );
    
        }
    
    
        function get_count() {
                return count($this->items);
        }
    }
    
    class myitem
    {
        function myitem( $id )
        {
            // nothing
        }
    }
    
    $f = new foo();
    
    $f->add_item( 1 );
    $f->add_item( 2 );
    
    $f->remove_item( 1 );
    
    echo $f->get_count();
    

    Also, is this PHP4? Because if not, you should look into some of the SPL stuff like ArrayObject or at least the the Countable and ArrayAccess interfaces.

    EDIT

    Here's a version using the interfaces directly

    <?php
    
    class foo implements ArrayAccess, Countable
    {
        protected $items = array();
    
        public function offsetExists( $offset )
        {
            return isset( $this->items );
        }
    
        public function offsetGet( $offset )
        {
            return $this->items[$offset];
        }
    
        public function offsetSet( $offset, $value )
        {
            $this->items[$offset] = $value;
        }
    
        public function offsetUnset( $offset )
        {
            unset( $this->items[$offset] );
        }
    
        public function count()
        {
            return count( $this->items );
        }
    
        public function addItem( $id )
        {
            $this[$id] = new myitem( $id );
        }
    }
    
    class myitem
    {
        public function __construct( $id )
        {
            // nothing
        }
    }
    
    $f = new foo();
    
    $f->addItem( 1 );
    $f->addItem( 2 );
    unset( $f[1] );
    
    echo count( $f );
    

    And here's a version as an implementation of ArrayObject

    <?php
    
    class foo extends ArrayObject
    {
        public function addItem( $id )
        {
            $this[$id] = new myitem( $id );
        }
    }
    
    class myitem
    {
        public function __construct( $id )
        {
            // nothing
        }
    }
    
    $f = new foo();
    
    $f->addItem( 1 );
    $f->addItem( 2 );
    unset( $f[1] );
    
    echo count( $f );