有這個陣列:
[
"id" => 5,
"name" => "Item 5",
"all_parents" => [
"id" => 4,
"name" => "Item 4",
"all_parents" => [
"id" => 3,
"name" => "Item 3",
"all_parents" => [
"id" => 2,
"name" => "Item 2",
"all_parents" => [
"id" => 1,
"name" => "Item 1",
"all_parents" => null
]
]
]
]
]
我創建了一個遞回 php 函式,將該陣列轉換為:
[
["id" => 1, "name" => "Item 1"],
["id" => 2, "name" => "Item 2"],
["id" => 3, "name" => "Item 3"],
["id" => 4, "name" => "Item 4"],
["id" => 5, "name" => "Item 5"],
]
代碼是這樣的:
private array $breadcrumb = [];
private function generateBreadcrumb($structure) : array
{
if($structure) {
$this->breadcrumb[] = array(
"id" => $structure['id'],
"name" => $structure['name'],
);
$this->generateBreadcrumb($structure['all_parents'] ?? []);
}
return array_reverse($this->breadcrumb);
}
如何在不依賴類屬性的情況下重新設計此方法$breadcrumb?
uj5u.com熱心網友回復:
通過遵循您的初始代碼,您可以執行以下操作:
function generateBreadcrumb($structure, &$output = []) : array
{
if ($structure) {
$output[] = array(
"id" => $structure['id'],
"name" => $structure['name'],
);
$this->generateBreadcrumb($structure['all_parents'] ?? [], $output);
}
return array_reverse($output);
}
然而,它可以改進,至少通過避免array_reverse()每次呼叫,但僅限于根呼叫。
uj5u.com熱心網友回復:
除了實作遞回函式之外,還可以使用內置的array_walk_recursive函式:
$arr = [
'id' => 5,
'name' => 'Item 5',
'all_parents' => [
'id' => 4,
'name' => 'Item 4',
'all_parents' => [
'id' => 3,
'name' => 'Item 3',
'all_parents' => [
'id' => 2,
'name' => 'Item 2',
'all_parents' => [
'id' => 1,
'name' => 'Item 1',
'all_parents' => null
]
]
]
]
];
function generateBreadcrumb($structure): array {
$retval = [];
array_walk_recursive($structure, function ($item, $key) use (&$retval) {
if ($key === 'id') {
$retval[] = [$key => $item];
} elseif ($key === 'name') {
$retval[array_key_last($retval)][$key] = $item;
}
});
return array_reverse($retval);
}
$result = generateBreadcrumb($arr);
注意array_walk_recursive只訪問葉子,所以除了最里面的'all_parents'之外,其他的都不會被訪問。
非遞回版本是這樣的:
function generateBreadcrumb(array $arr): array {
$retval = [];
$temp = &$arr;
do {
$retval[] = [ 'id' => $temp['id'], 'name' => $temp['name'] ];
$temp = &$temp['all_parents'];
} while ($temp !== null);
return array_reverse($retval);
}
uj5u.com熱心網友回復:
您可以在遞回樹時通過合并來累積不確定深度的資料。遞回時不需要引入任何新的變數來攜帶資料,也不需要array_reverse()回傳的資料。
以下技術將在$structure['all_parents']為真(非空)時優先遞回,并在遇到null all_parents最深子陣列中的值時停止遞回。從底部開始,idandname元素將被訪問并合并到行資料的空陣列或累積陣列中。
代碼:(演示)
class Recursing
{
public function generateBreadcrumb(array $structure): array
{
return array_merge(
$structure['all_parents']
? $this->generateBreadcrumb($structure['all_parents'])
: [],
[
['id' => $structure['id'], 'name' => $structure['name']]
]
);
}
}
$test = new Recursing;
var_export($test->generateBreadcrumb($arr));
輸出:
array (
0 =>
array (
'id' => 1,
'name' => 'Item 1',
),
1 =>
array (
'id' => 2,
'name' => 'Item 2',
),
2 =>
array (
'id' => 3,
'name' => 'Item 3',
),
3 =>
array (
'id' => 4,
'name' => 'Item 4',
),
4 =>
array (
'id' => 5,
'name' => 'Item 5',
),
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/434916.html
