Sorting objects by their properties



Sorting objects by their properties might seem complicated but it is quite simple in PHP. To demonstrate, I created class Node and a class NodeBox which creates the Nodes and stores them in an array. NodeBox is also capable of sorting its nodes.

Lets begin by looking at the Node class:

Class Node {
  private $nMass;

  public function Node($mass)
  {
    $this->nMass = $mass;	
  }

  public function getNodeMass()
  {
    return $this->nMass;
  }
}


Each node has a private data member $nMass. I can be access by getNodeMass() function. Now the NodeBox class.

Class NodeBox
{
  public $aNodes; // array of nodes

  public function NodeBox()
  {
    $this->aNodes = array();
  }

  public function createNodes() 
  {
    for($i = 0; $i < 5; $i++) {
      $this->aNodes[] = new Node(rand()%9);
    }
  }

  public function sortNodes() 
  {
    usort($this->aNodes, array($this,"cmp_nodemass"));
  }

  private function cmp_nodemass($x, $y)
  {
    // convert strings to floats and compare
    $a = intval($x->getNodeMass()); 
    $b = intval($y->getNodeMass());
    if ($a == $b) { return 0; }
    return ($a < $b) ? -1 : 1;
  }
}


createNodes() creates nodes with mass (0-9) using a random function. sortNodes() simply passes the right parameters to usort() the right parameters. The array of objects and the comparison function. cmp_nodemass() is the comparison function. $x and $y are Node objects in the array.
intval($x->getNodeMass())

$x is a Node object. getNodeMass() is a public function of Node. $x->getNodeMass() calls this function. It returns a the mass of the Node object as a string. We need to convert it to integer before making the comparison. Thus the intval() function.

cmp_nodemass() sorts in ascending order. To change to descending order, simply change $a < $b in the last line to $a > $b.

Time to call our classes:


$o = new NodeBox;
$o->createNodes();
print_r($o->aNodes);
print '<br>\n=============================================\n<br>';
$o->sortNodes();
print_r($o->aNodes);

Once you run the code on a browser, view page source to get a more readable view. The results should be something like:

Array
(
    [0] => Node Object
        (
            [nMass:private] => 4
        )

    [1] => Node Object
        (
            [nMass:private] => 3
        )

    [2] => Node Object
        (
            [nMass:private] => 3
        )

    [3] => Node Object
        (
            [nMass:private] => 2
        )

    [4] => Node Object
        (
            [nMass:private] => 3
        )

)

Array ( [0] => Node Object ( [nMass:private] => 2 ) [1] => Node Object ( [nMass:private] => 3 ) [2] => Node Object ( [nMass:private] => 3 ) [3] => Node Object ( [nMass:private] => 3 ) [4] => Node Object ( [nMass:private] => 4 ) )