我有以下数组结构:
| ID | CategoryName | ParentID
_________________________________
1 | Movies | -1
_________________________________
2 | Series | -1
_________________________________
3 | ActionMovies | 1
_________________________________
4 | HorrorMovies | 1
_________________________________
5 | ComedySeries | 2
_________________________________
6 | TVShows | -1
我的目标是达到以下结构
目标:
| ID | CategoryName | ParentID
_________________________________
1 | Movies | -1
_________________________________
3 | ActionMovies | 1
_________________________________
4 | HorrorMovies | 1
_________________________________
2 | Series | -1
_________________________________
5 | ComedySeries | 2
_________________________________
6 | TVShows | -1
或者用字解释:
- 父类别具有
ParentID = -1
(示例电影) - 所有类别都保留其原始 ID 号
- 应该直接列在他们的父类别之后(示例动作电影)
- 没有子项的根类别,列在数组的末尾。(示例电视广告)
如何使用 PHP 实现最佳效果?我无法访问原始的Mysql查询,因此这不是一个选项:)
我已从此代码开始,但我不确定这是正确的路径,并且工作量/可读性最少
$tmpList = Categories_Models_Main::getAllCategories();
$categoryData = array();
foreach ($tmpList as $index => $categoryObject) {
$categoryData[] = array('id' => $categoryObject->id,
'CategoryName' => $categoryObject->parentId,
'name' => $categoryObject->name);
}
///let us assume $categoryData is original state.
///Beginning of manipulation and re-sorting of $tmpList
foreach ($categoryData as $key => $value) {
$mainId[$key] = $value['id'];
$parentId[$key] = $value['parentId'];
}
array_multisort($parentId, $mainId, $categoryData);
将主数组一分为二,一个包含没有子项的节点,另一个包含其余项目。
使用array_multisort函数对项目数组进行排序,并使用所需的条件对没有子项的类别数组进行排序。最后一步是将没有子级的数组推到另一个。
这种形式不是最有效的,但第一种方法是有效的,在此之后,您可以分配时间来优化代码。
$input = array(
array("foo", "bar", "5"),
array("barr", "baz", "9"),
array("nyan", "nyu", "2")
);
usort($input, function($a, $b) {
if($a[2] < $b[2]) {
return -1;
} else if($a[2] > $b[2]) {
return 1;
} else {
return 0;
}
});
var_dump($input);
你的意思是这样吗?这个想法是使用您知道的条件手动比较数组的内容。由于要排序的事物是唯一的,因此必须始终实现如何排序的逻辑。使用 PHP,PHP 的排序函数大部分时间都是正确的。
我很确定这不能回答你的问题,但可能会给你一些如何让你的生活更轻松的想法。这是问题的javascript方法,但这样你甚至不必考虑对任何东西进行排序。您只需提供父母和孩子,它就会为您排序并随时可以使用。在我看来,这是一个相当不错的方式。然而,它可能与您要做的事情无关,但对于其他一些类似的问题,您会将其视为解决方案:https://developers.google.com/chart/interactive/docs/gallery/orgchart
解决这个问题的唯一方法是使用自下而上的方法(我指的是金字塔)。
解释
我们需要从数组中没有父级的行(条目)开始。就我而言,它是任何具有"parent_id = 0"的元素。一旦我们有了这些,我们需要为每个父元素构建子元素。
后一部分将通过调用排序方法递归完成,直到我们正在处理的元素没有子元素。排序方法的结果将向下传递到前一个数组点,直到数组完成。
法典
Class Categories {
private $cats;
public function getAllCategoriesSorted() {
/**
* $this->cats = [
* 'id' => x, 'parent_id' => x
* ];
*/
$this->cats = Category::get()->toArray();
# find categories with no parents
$keys = array_keys(array_column($this->cats, 'parent_id'), 0);
$return = [];
# loop through each and populate each one
foreach ($keys as $key) {
$return[$this->cats[$key]['id']] = $this->sortCategories($this->cats[$key]);
}
dd($return);
}
private function sortCategories($currentElement) {
# we need to check if current element has any children
$keys = array_keys(array_column($this->cats, 'parent_id'), $currentElement['id']);
if ($keys === false || empty($keys)) {
# we are dealing with childless element, we should return it as it is
return $currentElement;
}
# we are dealing with element that has children, we need to loop through each child
$currentElement['children'] = [];
foreach ($keys as $key) {
$currentElement['children'][$this->cats[$key]['id']] = $this->sortCategories($this->cats[$key]);
}
return $currentElement;
}
}
示例结果
array:2 [▼
65 => array:4 [▼
"id" => 65
"name" => "Parent 1"
"parent_id" => 0
"children" => array:14 [▼
66 => array:4 [▼
"id" => 66
"name" => "Child 1"
"parent_id" => 65
"children" => array:22 [▶]
]
87 => array:4 [▼
"id" => 87
"name" => "Child 2"
"parent_id" => 65
"children" => array:31 [▶]
]
117 => array:4 [▶]
118 => array:4 [▶]
120 => array:4 [▶]
124 => array:4 [▶]
125 => array:4 [▶]
127 => array:4 [▶]
225 => array:4 [▶]
305 => array:4 [▶]
434 => array:4 [▶]
321 => array:4 [▶]
348 => array:4 [▶]
468 => array:4 [▶]
]
]
64 => array:4 [▼
"id" => 64
"name" => "Parent 2"
"parent_id" => 0
"children" => array:5 [▼
128 => array:4 [▶]
132 => array:4 [▼
"id" => 132
"name" => "Child 3"
"parent_id" => 64
"children" => array:22 [▼
202 => array:3 [▶]
203 => array:3 [▼
"id" => 203
"name" => "Child 4"
"parent_id" => 132
]
204 => array:3 [▶]
205 => array:3 [▶]
206 => array:3 [▶]
207 => array:3 [▶]
208 => array:3 [▶]
209 => array:3 [▶]
210 => array:3 [▶]
211 => array:3 [▶]
212 => array:3 [▶]
213 => array:3 [▶]
214 => array:3 [▶]
215 => array:3 [▶]
216 => array:3 [▶]
217 => array:3 [▶]
218 => array:3 [▶]
220 => array:3 [▶]
221 => array:3 [▶]
222 => array:3 [▶]
223 => array:3 [▶]
224 => array:3 [▶]
]
]
134 => array:4 [▶]
394 => array:4 [▶]
454 => array:4 [▶]
]
]
]