PHP - 使用array_filter从哈希表(数组)中删除项目

3
在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而不返回false值的最佳方法(不需要编写单独的回调函数)。

谢谢:)

3个回答

8

没有官方的方法吗?当然有!取消设置

<?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或至少CountableArrayAccess接口。

编辑

这里是直接使用接口的版本

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

摆脱isset条件 ;) - Mario
哦,我猜这不是必需的。我没有测试过代码,但我猜它最终并不会抛出未设置unset()的警告。 - Peter Bailey

5
if ($this->items[$id]) {

可能会返回一个警告,应该使用array_key_exists或isset。

使用unset()删除一个项目似乎比赋值为false更干净(也将解决您的计数问题)。


3

对于Peter和Mario的答案,我赞同使用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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接