PHP配列、 'depth'のキーを持つ配列に再帰的に配列項目の深さを追加
-
10-07-2019 - |
質問
一番下のサンプル配列ごとに、配列内に埋め込まれた各配列の深さを追加できるようにしたい。例:
array ( 53 => array ( 'title' => 'Home', 'path' => '', 'type' => '118', 'pid' => 52, 'hasChildren' => 0, ),
以下に示すサンプル配列によると、深さは1であるため、次のようになります。
array ( 53 => array ( 'title' => 'Home', 'path' => '', 'type' => '118', 'pid' => 52, 'hasChildren' => 0, 'depth' => 1, ),
など...
私が行った再帰的配列関数の試みはすべて非常に恥ずかしいです。ただし、getDepth関数を持つRecursiveArrayIteratorを見てきました。現在の配列にそれを追加する方法について混乱しています...どんな助けも非常に感謝しています、ありがとう。
array ( 'title' => 'Website Navigation', 'path' => '', 'type' => '115', 'pid' => 0, 'hasChildren' => 1, 'children' => array ( 53 => array ( 'title' => 'Home', 'path' => '', 'type' => '118', 'pid' => 52, 'hasChildren' => 0, ), 54 => array ( 'title' => 'Features', 'path' => 'features', 'type' => '374', 'pid' => 52, 'hasChildren' => 1, 'children' => array ( 59 => array ( 'title' => 'artistic', 'path' => 'features/artistic', 'type' => '374', 'pid' => 54, 'hasChildren' => 1, 'children' => array ( 63 => array ( 'title' => 'galleries', 'path' => 'features/artistic/galleries', 'type' => '374', 'pid' => 59, 'hasChildren' => 1, 'children' => array ( 65 => array ( 'title' => 'graphics', 'path' => 'features/artistic/galleries/graphics', 'type' => '118', 'pid' => 63, 'hasChildren' => 0, ), 67 => array ( 'title' => 'mixed medium', 'path' => 'features/artistic/galleries/mixed-medium', 'type' => '118', 'pid' => 63, 'hasChildren' => 0, ), 64 => array ( 'title' => 'overview', 'path' => 'features/artistic/galleries', 'type' => '118', 'pid' => 63, 'hasChildren' => 0, ), 68 => array ( 'title' => 'photography', 'path' => 'features/artistic/galleries/photography', 'type' => '118', 'pid' => 63, 'hasChildren' => 0, ), 66 => array ( 'title' => 'traditional', 'path' => 'features/artistic/galleries/traditional', 'type' => '118', 'pid' => 63, 'hasChildren' => 0, ), ), ), 62 => array ( 'title' => 'overview', 'path' => 'features/artistic', 'type' => '118', 'pid' => 59, 'hasChildren' => 0, ), 69 => array ( 'title' => 'tutorials', 'path' => 'features/artistic/tutorials', 'type' => '374', 'pid' => 59, 'hasChildren' => 1, 'children' => array ( 71 => array ( 'title' => 'by category', 'path' => 'features/artistic/tutorials/by-category/', 'type' => '118', 'pid' => 69, 'hasChildren' => 0, ), 72 => array ( 'title' => 'by date', 'path' => 'features/artistic/tutorials/by-date/', 'type' => '118', 'pid' => 69, 'hasChildren' => 0, ), 70 => array ( 'title' => 'overview', 'path' => 'features/artistic/tutorials', 'type' => '118', 'pid' => 69, 'hasChildren' => 0, ), ), ), ), ), 58 => array ( 'title' => 'overview', 'path' => 'features', 'type' => '118', 'pid' => 54, 'hasChildren' => 0, ), 61 => array ( 'title' => 'projects / labs', 'path' => 'features/projects-labs/', 'type' => '374', 'pid' => 54, 'hasChildren' => 0, ), 60 => array ( 'title' => 'web development', 'path' => 'features/web-development', 'type' => '374', 'pid' => 54, 'hasChildren' => 1, 'children' => array ( 74 => array ( 'title' => 'articles', 'path' => 'features/web-development/articles/', 'type' => '374', 'pid' => 60, 'hasChildren' => 0, ), 73 => array ( 'title' => 'overview', 'path' => 'features/web-development', 'type' => '118', 'pid' => 60, 'hasChildren' => 0, ), 75 => array ( 'title' => 'tutorials', 'path' => 'features/web-development/tutorials', 'type' => '374', 'pid' => 60, 'hasChildren' => 0, ), ), ), ), ), 55 => array ( 'title' => 'Activity', 'path' => 'activity', 'type' => '374', 'pid' => 52, 'hasChildren' => 0, ), 56 => array ( 'title' => 'Blog', 'path' => 'blog', 'type' => '374', 'pid' => 52, 'hasChildren' => 0, ), 57 => array ( 'title' => 'About', 'path' => 'about', 'type' => '374', 'pid' => 52, 'hasChildren' => 1, 'children' => array ( 76 => array ( 'title' => 'the author', 'path' => 'about/the-author', 'type' => '118', 'pid' => 57, 'hasChildren' => 0, ), 77 => array ( 'title' => 'the website', 'path' => 'about/the-website', 'type' => '118', 'pid' => 57, 'hasChildren' => 0, ), ), ), ), ), ); print_r($example); ?>
解決
別の配列(サンプルコードに含まれていない上部にあると仮定します。 このようなものですか?
function array_set_depth($array, $depth = -1)
{
$subdepth = $depth + 1;
if ($depth < 0) {
foreach ($array as $key => $subarray) {
$temp[$key] = array_set_depth(($subarray), $subdepth);
}
}
if ($array['hasChildren'] && isset($array['children'])) {
foreach ($array['children'] as $key => $subarray) {
$temp[$key] = array_set_depth($subarray, $subdepth);
}
$array['children'] = $temp;
}
$array['depth'] = $depth;
return $array;
}
使用例、配列を値$ aに設定します:
$b = array_set_depth($a);
print_r($b);
編集:
素敵な印刷のために子供の前に深さを設定するには、これを行うことができます:
function array_set_depth($array, $depth = -1)
{
$subdepth = $depth + 1;
if ($depth < 0) {
foreach ($array as $key => $subarray) {
$temp[$key] = array_set_depth(($subarray), $subdepth);
}
return $temp;
}
$array['depth'] = $depth;
if ($array['hasChildren'] && isset($array['children'])) {
foreach ($array['children'] as $key => $subarray) {
$temp[$key] = array_set_depth($subarray, $subdepth);
}
unset($array['children']);
$array['children'] = $temp;
}
return $array;
}
他のヒント
このような再帰関数はそれを行う必要がありますか?
function setDepth(&$a, $depth)
{
$a['depth']=$depth;
foreach($a as $key=>$value)
{
if (is_array($value))
setDepth($a[$key], $depth+1);
}
}
注意すべきことは、配列は参照によって渡されるため、変更できることです。 setDepthの再帰呼び出しでもこの参照を使用することに注意してください。私は便宜上foreachを使用しましたが、$ value変数はコピーであり、これをsetDepthに渡すと、foreachループのスコープ内で短期間の変更のみが行われます。
この例で動作するようにPaulsコードを変更しました。
function setDepth(&$a, $depth = -1)
{
if (($depth > -1) && !($depth % 2))
$a['depth']= $depth / 2;
foreach($a as $key=>$value)
{
if (is_array($value))
setDepth($a[$key], $depth+1);
}
}
setDepth($a);
print_r($a);
このような方法でトリックを行う必要があります:
function setdepth($arr, $depth = 0)
{
foreach ($arr as $key => $val)
{
$arr[$key]['depth'] = $depth;
if ($arr[$key]['hasChildren'])
{
setdepth(&$arr[$key]['children'], $depth+1);
}
}
}
配列が値ではなくインデックスで始まる場合、iはより簡単になるため、使用例は次のようになります。
$arr[0] = $website;
setdepth(&$arr, 0);
ここで、websiteはサンプルの配列です
これは役に立つかもしれません:
function extend( $arr, $myArr=array() ) {
foreach( $arr as $key => $value ) {
if( is_array( $key ) ) {
extend( $arr[ $key ] );
} else {
$myArr[ $key ] = $arr[ $key ];
}
}
return $myArr;
}
&quot; extend&quot;と呼ばれる関数配列を新しい配列にコピーするだけでなく、既存の配列を拡張することもできます。
配列を拡張するには、2番目のパラメーターとして配置する必要があります。そうでない場合は、空の配列を配置します。 関数は配列プロパティを調べて、配列かどうかをチェックし、関数が再度呼び出されるかどうかを確認します。そうでない場合は、値を別の配列にコピーして返します。