Sort array by parent_id and level

Notice: This thread is very old.
VojtaSim
Member | 55
+
0
-

Hi,
I have a problem with sorting array of ActiveRows. Since ActiveRow is read-only in Nette 2.1, multidimensional array is out of options. Only option left is flat array sorted by parent_id and level where every element with parent_id equal to NULL is followed by elements with parent_id set to it's ID and so on.
I tried some options using uasort but each of them worked olny for 2 level array and 3rd level elements were shifted to the end.

uasort($categoriesArray, function ($a, $b) {
	if ( $a['id'] == $b['id'] ) {
		return 0;

	} else if ( $a['parent_id'] ) {
		if ( $a['parent_id'] == $b['parent_id'] ) {
			return ( $a['id'] < $b['id'] ? -1 : 1 );
		} else {
			return ( $a['parent_id'] >= $b['id'] ? 1 : -1 );
		}
	} else if ( $b['parent_id'] ) {
		return ( $b['parent_id'] >= $a['id'] ? -1 : 1);
	} else {
		return ( $a['id'] < $b['id'] ? -1 : 1 );
	}
});

I also tried create some kind of wrapper (inspired here) for ActiveRow to break the read-only status, but I end up with 500 Internal Error.

Desired array:

array (7)
	0 => Nette\Database\Table\ActiveRow #1d0f
		. . .
		id => 1,
		parent_id => NULL,
		level => 1,
		name => ...
	1 => Nette\Database\Table\ActiveRow #337c
		. . .
		id => 2,
		parent_id => 1,
		level => 2,
		name => ...
	2 => Nette\Database\Table\ActiveRow #b63a
		. . .
		id => 3,
		parent_id => 1,
		level => 2,
		name => ...
	3 => Nette\Database\Table\ActiveRow #80c7
		. . .
		id => 4,
		parent_id => NULL,
		level => 1,
		name => ...
	4 => Nette\Database\Table\ActiveRow #2664
		. . .
		id => 5,
		parent_id => 4,
		level => 2,
		name => ...
	5 => Nette\Database\Table\ActiveRow #8ec6
		. . .
		id => 6,
		parent_id => ,
		level => 3,
		name => ...

A few notes: array shouldn't be sorted by id

VojtaSim
Member | 55
+
0
-

Ok never mind, I figured it out myself

private function buildTree($items, $parentId = 0, &$result = array()){
	foreach ($items as $key => $value) {
		if ($value['parent_id'] == $parentId) {
			if ($value['title'] == 'Unsorted')  // Unsorted will be always on top
				array_unshift($result, $value);
			else
				array_push($result, $value);

			unset($items[$key]);

			$oldParent = $parentId;
			$parentId = $value['id'];
			$this->buildTree($items, $parentId, $result);
			$parentId = $oldParent;
		}
	}
	return $result;
}