I have an array that looks like this:
[0] => Array
(
[id] => 111
[parent_id] => 222
[field_1] => Main document
)
[1] => Array
(
[id] => 123
[parent_id] => 222
[field_1] => Main document
)
[2] => Array
(
[id] => 777
[parent_id] => 111
[field_1] => Child document
)
[3] => Array
(
[id] => 345
[parent_id] => 222
[field_1] => Main document
)
[4] => Array
(
[id] => 789
[parent_id] => 123
[field_1] => Child document
)
[5] => Array
(
[id] => 567
[parent_id] => 345
[field_1] => Child document
)
您可能会注意到,在字段1中有主文档和子文档。子文档的[parent_id]等于主文档的[id]。我该如何按ID和父ID对它们进行排序,以便在每个主文档之后都应该是子文档?我知道我应该遍历它,但是有些东西我无法保留,并且没有按照我想要的方式进行排序。
这应该是这样:
[0] => Array
(
[id] => 111
[parent_id] => 222
[field_1] => Main document
)
[1] => Array
(
[id] => 777
[parent_id] => 111
[field_1] => Child document
)
[2] => Array
(
[id] => 123
[parent_id] => 222
[field_1] => Main document
)
[3] => Array
(
[id] => 789
[parent_id] => 123
[field_1] => Child document
)
[4] => Array
(
[id] => 345
[parent_id] => 222
[field_1] => Main document
)
[5] => Array
(
[id] => 567
[parent_id] => 345
[field_1] => Child document
)
基本上,您需要做的是将初始数组分为两部分:主文档数组和子文档数组。然后,只需遍历这些数组并组成一个新数组,在该数组中主文档后跟一系列子元素。
请注意,这是用php7.4编写的,我可能使用了以前版本php中没有的某些语法。
// extract main documents and sort them by id
$main_documents = array_filter($input, fn ($document) => $document['field_1'] === 'Main document');
usort($main_documents, function ($a, $b) {
return ($a['id'] <=> $b['id']);
});
// extract child documents and sort them by parent id
$child_documents = array_filter($input, fn ($document) => $document['field_1'] === 'Child document');
usort($child_documents, function ($a, $b) {
return ($a['parent_id'] <=> $b['parent_id']);
});
$output = [];
// go through each main document and insert it into the output array
foreach ($main_documents as $main_index => $main_document) {
$output[] = $main_document;
// go through all children and see whether they are a child of current main document
foreach ($child_documents as $child_index => $child_document) {
// if they are then insert this child after the main element
if ($main_document['id'] === $child_document['parent_id']) {
$output[] = $child_document;
// delete inserted child element from the children array so that next iteration can be faster
unset($child_documents[$child_index]);
}
}
// delete current main element from the array so that next iteration can be faster
unset($main_documents[$main_index]);
}
还有一个用于初始输入数组的较短版本:
$output = [];
foreach ($input as $main_index => $document) {
if ($document['field_1'] === 'Main document') {
$output[] = $document;
unset($input[$main_index]);
foreach ($input as $subloop_index => $subloop_document) {
if ($document['id'] === $subloop_document['parent_id']) {
$output[] = $subloop_document;
unset($input[$subloop_index]);
}
}
}
}
尽管我的回答不是很有效-嵌套循环永远不是一个好习惯,但是如果性能不是代码中的问题或效果可忽略,那么我认为应该这样做。