1

だから私の例の入力は

$example_1 = Array (
    0 => Array (
        'category'     => 'body',
        'sub-category' => 'intro',
        'id'           => 'header',
        'copy'         => 'Hello',
    ),
    1 => Array (
        'category'     => 'body',
        'sub-category' => 'intro',
        'id'           => 'footer',
        'copy'         => 'Bye',
    ),
);

$example_2 = Array (
    0 => Array (
        'category'     => 'body',
        'sub-category' => 'intro',
        'sub-sub-category' => 'header',
        'sub-sub-child-category' => 'left',
        'id'           => 'title',
        'copy'         => 'Hello',
    ),
    1 => Array (
        'category'     => 'body',
        'sub-category' => 'intro',
        'sub-sub-category' => 'footer',
        'sub-sub-child-category' => 'right',
        'id'           => 'title',
        'copy'         => 'Bye',
    ),
);

変身したい

$example_output_1 = Array (
    'body' => Array (
        'intro' => Array (
            'header' => Array (
                'title' => 'Hello',
            ),
            'footer' => Array (
                'title' => 'Bye',
            ),
        ),
    ),
);

$example_output_2 = Array (
    'body' => Array (
        'intro' => Array (
            'header' => Array ( 
                'left' => Array (
                    'title' => 'Hello',
                ),
            ),
            'footer' => Array (
                'right' => Array (
                    'title' => 'Bye',
                )
            ),
        ),
    ),
);

配列の深さは動的であることに注意してください(設定されていません。「コピー」を押すまでにのみ、配列の深さを示します)。

再帰を正しく取得しようとすると問題が発生します。私が持っていた基本的ですが非常に大まかなアルゴリズムは次のとおりでした-行をループします-行の内容をループします-インデックスが「コピー」の場合、最終的な値は現在の値です。-次に、アレイを構築します

なんとか配列の1行だけで処理できるようになりましたが、非常に乱雑で少しパッチが多かったので、最初からやり直す必要があると感じました。更新:要求に応じて困惑するコードを添付しました(悲鳴を上げないでください!; p)

function buildArray($row, $start = true) {

    if ($start) {
        $result = array();
    }

    if ( ! is_array($row) ) {
        return $row;
    }

    // Get the first element of the array include its index
    $cellValue = null;
    $colId = null;
    foreach($row AS $index => $value) {
        $cellValue = $value;
        $colId = $index;
        break; 
    }

    // Reduce the array by one
    $tempRow = $row;
    $temp = array_shift($tempRow);

    if ($colId == 'copy') {
        $result[$cell] = buildArray($cellValue, $locale, false);
    } else {
      $result[$cell] = buildArray($tempRow, $locale, false);
    }

    return $result;
} 

どんな助けでも大歓迎です。

4

2 に答える 2

3

非常に簡単なはずです:

$originalArray = array(); // <-- should contain your values
$newArray = array();

foreach( $originalArray as $item )
{
    $category = $item['category'];
    $subcategory = $item['sub-category'];

    if ( empty( $newArray[$category] ) )
    {
        $newArray[$category] = array();
    }
    if ( empty( $newArray[$category][$subcategory] ) )
    {
        $newArray[$category][$subcategory] = array();
    }

    $newArray[$category][$subcategory][$item['id']] = $item['copy'];
}

ここで実際に見てください:http://codepad.viper-7.com/9bDiLP


更新:無制限の再帰が必要であることを指定したので、ここでそのショットを示します。

$originalArray = array(); // <-- Your values go here
$newArray = array();

foreach ( $originalArray as $item )
{
    $inception = &$newArray; // http://www.imdb.com/title/tt1375666/

    foreach ( $item as $key => $val )
    {
        if ( $key != 'id' )
        {
            if ( empty($inception[$val]) )
            {
                $inception[$val] = array();
            }
            $inception = &$inception[$val];
        }
        else
        {
            $inception[ $val ] = $item['copy'];
            break;
        }
    }
}

...そしてここにデモがあります: http://codepad.viper-7.com/F9hY7h

于 2012-06-06T22:19:09.590 に答える
1

再帰は関数の末尾でのみ発生するため、これは繰り返し解決できます。次のコードは単純化したものです。古い配列を反復処理しながら、新しい層状配列を構築します。

各エントリを変換した後、 を使用してマージされarray_merge_recursiveます。

function transform($a)
{
    // create new array and keep a reference to it
    $b = array(); $cur = &$b;
    foreach ($a as $key => $value) {
        if ('id' === $key) {
            // we're done, add value to the array built so far using id and copy
            $cur[$value] = $a['copy'];
            break;
        } else {
            // create one more level
            $cur[$value] = array();
            // and update the reference
            $cur = &$cur[$value];
        }
    }
    // all done
    return $b;
}

// $example_2 is your multi-dimensional array
$merged = call_user_func_array('array_merge_recursive', 
    array_map('transform', $example_2)
);
于 2012-06-06T22:31:50.267 に答える