note 94637 deleted from function.usort by cmb
| From: | cmb@php.net | Date: | Wed, 22 Jun 2016 17:29:33 +0000 |
| Subject: | note 94637 deleted from function.usort by cmb | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-205789@lists.php.net to get a copy of this message | ||
Note Submitter: Rogier
----
<?php
// I have seen many examples of sorting, almost all of which
// are too specific and require one implementation per property
// on which to sort.
// So I decided to use Reflection, implementing a more generic approach that in fact turned out
// to resemble an approach I used in the early days of .NET...
// Intentionally, I did not do any checking on existing
// items. This is just to keep simplicity and to
// demonstrate the sorting functionality.
// A more real-life appraoach would require e.g. a collection that is based
// on implementing the Iterator, ArrayAccess and Countable interfaces.
// Take note that this implementation is specific for PHP5+ only
// This code was tested on PHP 5.0.4
class SortableItem
{
static public $sortProperty;
static function USortAsc($a, $b)
{
/*@var $_pd ReflectionProperty*/
$_pd = self::$sortProperty;
if ($_pd !== null)
{
if ($_pd->getValue($a) === $_pd->getValue($b))
return 0;
else
return (($_pd->getValue($a) < $_pd->getValue($b))?-1:1);
}
return 0;
}
static function USortDesc($a, $b)
{
return -(self::USortAsc($a,$b));
}
}
class Item extends SortableItem
{
public $name;
public $index;
public $description;
function __construct($nam,$idx,$desc)
{
$this->name = $nam;
$this->index = $idx;
$this->description = $desc;
}
function __toString()
{
return "$this->index; $this->name; $this->description\n";
}
}
class ItemCollection
{
protected $_array = array();
protected $_itemDescriptor;
function __construct()
{
$this->_itemDescriptor = new ReflectionClass('Item');
}
function Add(Item $item)
{
$this->_array[] = $item;
}
function Sort($property, $asc=true)
{
// this is where sorting logic takes place
$_pd = $this->_itemDescriptor->getProperty($property);
if ($_pd == null)
{
user_error('Property '.$property.' does not exist in class
'.$this->_itemDescriptor->getName(), E_WARNING);
return;
}
// set sortDescriptor
Item::$sortProperty = $_pd;
// and apply sorting
usort($this->_array, array('Item',
($asc?'USortAsc':'USortDesc')));
}
function getItems(){return $this->_array;}
}
//testing it....
$utime = microtime(true);
$coll = new ItemCollection();
$coll->Add( new Item('apple',0,'a sour fruit') );
$coll->Add( new Item('pear',54,'delicious pears') );
$coll->Add( new Item('mango',245,'bread and butter') );
echo PHP_EOL,'sort by index, asc',PHP_EOL;
$coll->Sort('index',true);
$items = $coll->getItems();
foreach($items as $item)
{
echo $item->__toString();
}
echo PHP_EOL,'sort by index, desc',PHP_EOL;
$coll->Sort('index',false);
$items = $coll->getItems();
foreach($items as $item)
{
echo $item->__toString();
}
echo PHP_EOL,'sort by name, asc',PHP_EOL;
$coll->Sort('name',true);
$items = $coll->getItems();
foreach($items as $item)
{
echo $item->__toString();
}
echo PHP_EOL,'sort by name, desc',PHP_EOL;
$coll->Sort('name',false);
$items = $coll->getItems();
foreach($items as $item)
{
echo $item->__toString();
}
$utime = microtime(true)-$utime;
echo PHP_EOL,' sorting all took ',round(1000*$utime,2),' ms';
?>