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.