PHP: array sorting

I have an array with data from a MySQL table in a nested set model that I would like to sort, not only in alphabetical order, but also with child nodes immediately after the parent node. An example is an array to be sorted (before sorting):

Array ( [0] => Array ( [id] => 1 [name] => Kompetenser [parent] => 0 [depth] => 0 ) [1] => Array ( [id] => 2 [name] => Administration [parent] => 1 [depth] => 1 ) [2] => Array ( [id] => 11 [name] => Organisation [parent] => 2 [depth] => 2 ) [3] => Array ( [id] => 4 [name] => Arbetsledning [parent] => 2 [depth] => 2 ) [4] => Array ( [id] => 17 [name] => Planering [parent] => 2 [depth] => 2 ) [5] => Array ( [id] => 9 [name] => Hantverke [parent] => 1 [depth] => 1 ) [6] => Array ( [id] => 10 [name] => Snickeri [parent] => 9 [depth] => 2 ) [7] => Array ( [id] => 12 [name] => Sprรฅk [parent] => 1 [depth] => 1 ) [8] => Array ( [id] => 13 [name] => Tolk [parent] => 12 [depth] => 2 ) [9] => Array ( [id] => 15 [name] => Arabiska [parent] => 13 [depth] => 3 ) [10] => Array ( [id] => 14 [name] => Persiska [parent] => 13 [depth] => 3 ) [11] => Array ( [id] => 16 [name] => Polska [parent] => 13 [depth] => 3 ) [12] => Array ( [id] => 18 [name] => Apotekare [parent] => 1 [depth] => 1 ) [13] => Array ( [id] => 19 [name] => Dotkorand [parent] => 1 [depth] => 1 ) [14] => Array ( [id] => 21 [name] => Atomfysik [parent] => 19 [depth] => 2 ) [15] => Array ( [id] => 20 [name] => Fysik [parent] => 19 [depth] => 2 ) [16] => Array ( [id] => 22 [name] => Ekonom [parent] => 1 [depth] => 1 ) [17] => Array ( [id] => 23 [name] => Industriell ekonomi [parent] => 22 [depth] => 2 ) [18] => Array ( [id] => 24 [name] => Filosofi [parent] => 1 [depth] => 1 ) ) 

I want an array this way (after sorting):

 Array ( [0] => Array ( [id] => 1 [name] => Kompetenser [parent] => 0 [depth] => 0 ) [1] => Array ( [id] => 2 [name] => Administration [parent] => 1 [depth] => 1 ) [3] => Array ( [id] => 4 [name] => Arbetsledning [parent] => 2 [depth] => 2 ) [2] => Array ( [id] => 11 [name] => Organisation [parent] => 2 [depth] => 2 ) [4] => Array ( [id] => 17 [name] => Planering [parent] => 2 [depth] => 2 ) [12] => Array ( [id] => 18 [name] => Apotekare [parent] => 1 [depth] => 1 ) [13] => Array ( [id] => 19 [name] => Dotkorand [parent] => 1 [depth] => 1 ) [14] => Array ( [id] => 21 [name] => Atomfysik [parent] => 19 [depth] => 2 ) [15] => Array ( [id] => 20 [name] => Fysik [parent] => 19 [depth] => 2 ) [16] => Array ( [id] => 22 [name] => Ekonom [parent] => 1 [depth] => 1 ) [17] => Array ( [id] => 23 [name] => Industriell ekonomi [parent] => 22 [depth] => 2 ) [18] => Array ( [id] => 24 [name] => Filosofi [parent] => 1 [depth] => 1 ) [5] => Array ( [id] => 9 [name] => Hantverke [parent] => 1 [depth] => 1 ) [6] => Array ( [id] => 10 [name] => Snickeri [parent] => 9 [depth] => 2 ) [7] => Array ( [id] => 12 [name] => Sprรฅk [parent] => 1 [depth] => 1 ) [8] => Array ( [id] => 13 [name] => Tolk [parent] => 12 [depth] => 2 ) [9] => Array ( [id] => 15 [name] => Arabiska [parent] => 13 [depth] => 3 ) [10] => Array ( [id] => 14 [name] => Persiska [parent] => 13 [depth] => 3 ) [11] => Array ( [id] => 16 [name] => Polska [parent] => 13 [depth] => 3 ) ) 

As you can see, I want all messages with parent 2 right after messages with ID 2, etc.

Any help would be greatly appreciated. Thank you in advance.

+4
source share
4 answers

The problem is solved - I made two simple functions. I hope other people can take advantage of this:

 class data_comp { var $fetched_tree = array(); function tree_fetch($parent = 0) { $query = 'SELECT node.id, node.name, node.parent, (COUNT(parent.name) - 1) AS depth FROM test_competence AS node, test_competence AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.name'; $result = mysql_query($query) or die(mysql_error()); $tree = array(); while($data = mysql_fetch_assoc($result)) { $tree[$data['parent']][$data['id']] = array('name' => $data['name'], 'depth' => $data['depth']); } $this->tree_print($tree, $parent); } function tree_print($tree, $parent) { foreach($tree[$parent] as $id => $value) { $this->fetched_tree[] = array('id' => $id, 'name' => $value['name'], 'depth' => $value['depth']); if(isset($tree[$id]) && is_array($tree[$id])) { $this->tree_print($tree, $id); } } } } 

Thank you for your time. Any improvements are more than welcome.

0
source

Do not do this in PHP!

MySQL server is specially designed for querying and sorting data, reading in MySQL ORDER BY syntax. Running this on a MySQL server will save on runtime, CPU usage, and memory consumption.

+4
source

Use the php uasort() function to define your own comparison function.

But using MySQL's sorting capabilities would be more appropriate if possible in your case.

+2
source

You want to sort it, as in a database, multilayer. I donโ€™t think uasort can help with this problem because you want to bind the children to the parent.

 foreach ($arr as &$val) { $arr2[$val['id']] = &$val; } ksort($arr2); foreach ($arr2 as $id => &$val) { $parent = $val['parent']; if ($parent == 0) { continue; } $arr2[$parent]['children'][$id] = &$val; } function flattenArrayByChildren($arr) { foreach ($arr as $id => $val) { if (isset($val['children'])) { $temp = flattenArrayByChildren($val['children']); unset($val['children']); $out[$id] = $val; $out = $out + $temp; } else { $out[$id] = $val; } } return $out; } $arr2 = array(1 => $arr2[1]); $out = flattenArrayByChildren($arr2); var_dump($out); 

If you absolutely want to save the key, you can simply add it to $ val in the first foreach and get it in the flattenArrayByChildren recursive function and use it as the key.

0
source

All Articles