У меня есть массив с данными из таблицы MySQL во вложенной модели набора, которую я хотел бы отсортировать, а не только в алфавитном порядке, но также и с дочерними узлами непосредственно после родительского узла. Пример: массив, подлежащий сортировке (перед сортировкой):
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 ) )
Я хочу массив таким образом (после сортировки):
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 ) )
Как вы можете видеть, я хочу, чтобы все сообщения с родителем 2 сразу после сообщения с идентификатором 2 и т. Д.
Любая помощь будет высоко оценен. Заранее спасибо.
Не делайте этого в PHP!
Сервер MySQL специально разработан для запроса и сортировки данных, чтения в синтаксисе MySQL « ORDER BY ». Выполнение этого на сервере MySQL позволит сэкономить время выполнения, загрузку процессора и потребление памяти.
Используйте uasort()
php для определения вашей собственной функции сравнения.
Но использование возможностей сортировки MySQL было бы более уместным, если это возможно в вашем случае.
Вы хотите отсортировать его, как в БД, многослойный. Я не думаю, что uasort может помочь с этой проблемой, потому что вы хотите прикрепить детей к родителям.
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);
не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);
Если вы абсолютно хотите сохранить ключ, вы можете просто добавить его к $ val в первый foreach и получить его в рекурсивной функции flattenArrayByChildren и использовать в качестве ключа.
Проблема решена – я сделал две простые функции. Я надеюсь, что и другие люди могут использовать это:
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); } } } }
Спасибо за ваше время. Любые улучшения более чем приветствуются.