PHP - удалить элемент из хеш-таблицы (массива) с помощью array_filter - PullRequest
3 голосов
/ 29 апреля 2009

В PHP я знаю, что не существует официального способа удаления элементов после их помещения в массив. Но должно быть решение "наилучшего метода" для моей проблемы. Я полагаю, что это может лежать в функции array_filter.

По сути, у меня есть объект корзины, в котором хранятся элементы в хеш-таблице. Представьте, что вы можете купить только один предмет за раз.

Я делаю

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

get_count() по-прежнему возвращает 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);
}

Что люди считают лучшим методом для использования в get_count? Я не могу найти лучший способ использовать array_filter, который просто не возвращает ложные значения (без написания отдельного обратного вызова).

Спасибо:)

Ответы [ 3 ]

8 голосов
/ 29 апреля 2009

Нет официального пути? Конечно, есть! 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();

Кроме того, это PHP4? Потому что, если нет, вам следует изучить некоторые из компонентов SPL, такие как ArrayObject или хотя бы интерфейсы Countable и ArrayAccess .

EDIT

Вот версия, использующая интерфейсы напрямую

<?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 );

А вот версия как реализация 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 );
5 голосов
/ 29 апреля 2009
if ($this->items[$id]) {

Может возвращать предупреждение, следует использовать array_key_exists или isset.

unset () выглядит чище, чем присвоение false при удалении элемента (также избавит вас от проблемы с подсчетом).

3 голосов
/ 29 апреля 2009

+ 1 к ответам Питера и Марио: использование unset() является правильным способом удаления элементов из массива.

Я просто хотел оставить записку, чтобы объяснить, почему ваш метод не работает. Использование count() будет подсчитывать количество значений в массиве. false, хотя вы можете представить, что это означает «ничто», на самом деле это значение. Обычно, если вы хотите указать «нет значения», используйте null.

Вы также можете сбросить элемент массива, установив его на null, хотя посмотрите на код ниже, чтобы увидеть разницу.

$x = array("a", "b", "c");

var_dump(isset($x[0]));   // bool(true)
var_dump(isset($x[1]));   // bool(true)
var_dump(isset($x[2]));   // bool(true)
echo count($x);           // 3

$x[2] = null;
var_dump(isset($x[2]));   // bool(false) -- the value is not set any longer
echo count($x);           // 3  -- but it doesn't remove it from the array

unset($x[1]);
var_dump(isset($x[1]));   // bool(false)
echo count($x);           // 2
...