3

$tasksネストされた構造を説明するサンプルの 2d配列があります。

Array
(
    [14] => Array
        (
            [Id] => 14
            [parentId] => null
            [Name] => T1
        )

    [40] => Array
        (
            [Id] => 40
            [parentId] => null
            [Name] => T5
        )

    [41] => Array
        (
            [Id] => 41
            [parentId] => null
            [Name] => T4
        )

    [22] => Array
        (
            [Id] => 22
            [parentId] => 14
            [Name] => T2
        )

    [43] => Array
        (
            [Id] => 43
            [parentId] => 22
            [Name] => T2 child
        )

    [42] => Array
        (
            [Id] => 42
            [parentId] => 14
            [Name] => T3
        )

)

以下のコードを使用して、これを適切なツリー構造に変換しています。

$sortedArray = array();
// get first level
foreach($tasks as $k => $v){
    if($v['parentId'] == 'null'){
        $sortedArray[$k] = $v;
        unset($tasks[$k]);
    }
}
// sort parents
asort($sortedArray);

function getChildren(array & $a1, array & $a2){
    foreach($a1 as $k => $v){
        findChildren($v, $a2, $k);      
    }
}

function findChildren($rec1, array & $a2, $key){

    foreach($a2 as $k => $v){
        if($rec1['parentId'] == $v['Id']){
            $a2[$k]['children'][$rec1['Id']] = $rec1;
            unset($tasks[$key]);
        } else {
            if (isset($v['children'])){
                findChildren($rec1, $a2[$k]['children'], $key);
            }
        }
    }
}

findChildren($tasks, $sortedArray);

このコードを実行した後の出力$sortedArrayは次のようになります。

Array
(
    [14] => Array
        (
            [Id] => 14
            [parentId] => null
            [Name] => T1
            [children] => Array
                (
                    [22] => Array
                        (
                            [Id] => 22
                            [parentId] => 14
                            [Name] => T2
                            [children] => Array
                                (
                                    [43] => Array
                                        (
                                            [Id] => 43
                                            [parentId] => 22
                                            [Name] => T2 child
                                        )

                                )

                        )

                    [42] => Array
                        (
                            [Id] => 42
                            [parentId] => 14
                            [Name] => T3
                        )

                )

        )

    [40] => Array
        (
            [Id] => 40
            [parentId] => null
            [Name] => T5
        )

    [41] => Array
        (
            [Id] => 41
            [parentId] => null
            [Name] => T4
        )

)

問題は、現在の状態でこの出力配列で json_encode を呼び出した後、次のようになることです。

{"14":{"Id":"14","parentId":"null"...

そのため、ネストされたすべての配列がインデックスとともに挿入されます。を使用して最初のレベルを修正できることはわかっていますarray_values。しかし、すべてのレベルでこれを行う簡単な方法はありますか? それがなければ、「子供」は配列ではなくオブジェクトになり、満足のいくものではありません。

4

3 に答える 3

7

コードは投稿に含まれていませんが$tasks、連想配列として作成されました。あなたの例で$tasksは、連想配列と同じように繰り返します。

foreach($tasks as $k => $v){
    ...
}

$tasks数値配列の場合と同じように、に子を追加する必要があります。違いはこれです:

//associative array
$test = array();
$test["43"] = "hello";
$test["40"] = "hello1";
$test["23"] = "hello2";
print_r($test);

//numeric array
$testb = array(); 
$testb[] = "hello";
$testb[] = "hello1";
$testb[] = "hello2";
print_r($testb);

実例:http ://codepad.org/tsOhX88h

数値配列を使用すると、問題として引用した最上位のインデックス(たとえば、14){"14":{"Id":"14","parentId":"null"...は存在しなくなります。

簡単な最後のステップとして、このコードを使用して、アイテムを連想配列から新しい数値配列にプッシュします。

$finalArray = array();
foreach ($sortedArray as $key=>$val ){
    $finalArray[] = $sortedArray[$key];
}
print_r($finalArray);

実例:http ://codepad.org/uSGSr1DC

または、次のコマンドを使用して1回で実行できますarray_values

$finalArray = array();
$finalArray = array_values($sortedArray);
print_r($finalArray);

実例:http ://codepad.org/D7uBSRr8

于 2012-08-21T00:51:53.533 に答える
1

たまたまこのようにした場合、json_encode呼び出しを含めませんでした...

json_encode(array_values($sortedArray), JSON_FORCE_OBJECT);

とにかく力は数値インデックスを入れます。これがあなたに役立つかどうかはわかりませんが、同じ問題を見ている他の誰かを助けるかもしれません.

于 2015-03-22T01:53:02.060 に答える
0

わかりましたので、次のようなものを思いつくことができました:

function makeIndexed(array & $arr, array & $par = null){
    if(is_null($par)){
        $arr = array_values($arr);
    } else {
        $par['children'] = array_values($arr);
    }

    for($i=0; $i<count($arr); $i++) {   
        $temp = @$arr[$i]['children'];
        if(isset($temp)) {
            makeIndexed($arr[$i]['children'], $arr[$i]);
        }       
    }
}

そして今呼び出すとmakeIndexed($sortedArray);、有効な JSON が得られます。ここで、「子」はノードの配列であり、オブジェクトではありません。このコードはおそらく醜く、パフォーマンスに欠けるという事実を認識していますが、少なくとも適切な結果を生成します。誰かがよりクリーンで短いものを作成できる場合は、これを正解として喜んでマークします。

于 2012-08-21T07:35:14.473 に答える