1

マルチレベルの配列があります。レベル (サブアレイ) の数は不明です。私が知っている唯一のことは、各レベルに特定の(既知の)キーがあることです。

次の例を考えてみましょう。

Array
(
    [number] => 21
    [otherkey] => value
    [sub] => Array
        (
            [count] => 
            [number] => 29
            [some] => thing
            [range] => Array
                (
                   ...
                )

            [sub] => Array
                (
                    [count] => 1
                    [number] => 16
                    [key] => value
                    [date] => 2013-07-25
                    [sub] => Array
                        (
                            [count] => 0
                            [number] => 4
                            [key] => value
                            [sub] => Array
                                (
                                    [count] => 1
                                    [number] => 24
                                    [key] => value
                                    [sub] => last
                                )

                        )

                )

        )

)

私の目標は、すべての'number'キーを反復処理して「偶数」または「奇数」のようなテキストを作成することですnumber_str、結果は各レベルで独自のキー (たとえば ) の下に保存する必要があります

したがって、変更された配列は次のようになります。

 Array
    (
        [number] => 21
        [otherkey] => value
        [sub] => Array
            (
                [count] => 
                [number] => 29
                [some] => thing
                [range] => Array
                    (
                     ...
                    )
                [sub] => Array
                    (
                        [count] => 1
                        [number] => 16
                        [key] => value
                        [date] => 2013-07-25
                        [sub] => Array
                            (
                                [count] => 0
                                [number] => 4
                                [key] => value
                                [sub] => Array
                                    (
                                        [count] => 1
                                        [number] => 24
                                        [key] => value
                                        [sub] => last
                                        [number_str] => even //new key
                                    )
                                [number_str] => even //new key

                            )
                        [number_str] => even //new key

                    )
                [number_str] => odd //new key

            )
        [number_str] => odd //new key
    )

だから私は RecursiveIteratorIterator を使用しようとしました

$rai = new RecursiveArrayIterator($data);
$rii = new RecursiveIteratorIterator($rai);

foreach ($rii as $idx => $level) {
    if($idx === 'number')
    {
        $str = ($level % 2) ? 'odd' : 'even';
        $rii->offsetSet('number_str', $str);
    }
}

しかし、うまくいきませんでした。 だから私は一種の「回避策」を見つけました。各サブ配列がstdClassのオブジェクトである場合、私が期待することはできるようです

元の配列 (およびすべてのサブ配列) を stdClass に変換します

$data = json_encode(json_decode($data)); // ..dirty gimmick. Possible performance killer ?

$rai = new RecursiveArrayIterator($data);
$rii = new RecursiveIteratorIterator($rai);

foreach ($rii as $idx => $level) {
    //same logic as above...
}

var_dump($rai);

結果が欲しかったように見えますが、唯一の問題は、すべてのサブレベルが stdClass のインスタンスになっていることです

コードオンライン -> http://ideone.com/PIiZOX

QUESTION同じ結果を得る方法はありますか? json_decode/のギミックなしでjson_encode、出力は通常の Array になりますか?

PS :ありarray_walk()ますが、オプションではありません

更新:質問は正しい結果を得ることに関するものではないことに言及する必要があります。カスタムの recursiv 関数 (およびおそらくarray_walk_recursive()) がそのトリックを実行することはわかっています。可能な解決策として、SPL RecursiveIteratorsについて詳しく説明します。strClassなぜそれがesで機能し、なぜ通常の配列では機能しないのか、私はただ不思議に思います。

obeve の Array の例は実際のユースケースではありません。ご想像のとおり、実際の使用例は、DB からのデータを使用する配列 (場合によっては 600 行を超える) です。それらのいくつかにはサブアレイがあります。私が知っている唯一のことは、(特定のルールによって)変更する必要があるキーです。パフォーマンスが主な基準

4

3 に答える 3

1
function even_or_odd(&$arr){
    if(is_array($arr)){
        if (isset($arr['number'])){
            if ($arr['number']%2 == 1){
                $arr['number_str'] = 'odd';
            } else {
                $arr['number_str'] = 'even';
            }
        }
        foreach( $arr as $key => &$val ){
            if(is_array($val)){
                self::even_or_odd($val);
            }
        }
    }
}
于 2013-07-25T20:08:16.717 に答える