Hi
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 :)
-
if ($this->items[$id]) {
May return a warning, should use array_key_exists or isset.
unset() seems cleaner than assigning false when removing an item (will also get rid of your count problem).
-
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 );
Mario : Get rid of the isset condition ;)Peter Bailey : Oh, I guess it's not needed. I didn't test the code, but I guess it doesn't throw a warning with unset() after all. -
+1 to both Peter's and Mario's answers: using
unset()
is the correct way to remove items from an array.I just wanted to leave a note to explain why your method wasn't working. Using
count()
will count the number of values in an array.false
, though you could imagine it as meaning "nothing", is still actually a value. Typically if you want to actually specify "no value" then usenull
.You can also unset an array element by setting it to
null
, though look at the code below to see the difference.$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
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.