0

基本的に、私は使用したい

$foo = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack));

方法論ですが、通過するためにフラットな配列を返す代わりにforeach()、構造を維持しますが、単一のひ孫ノードとその親ノードのみを返します。これはPHPで可能ですか?


私は自分の会社の(恐ろしい)コードベースのいくつかを最適化する任務を負っています。配列を繰り返し処理してキーを検索する関数を見つけました。これを単純なものに置き換えることはできませんarray_search()。または、カスタム関数がaまたは。array_key_exists()だけでなく、一致した(見つかった)キーの親ノードも返すためです。truefalse

他の組み込み関数(つまり、可能な限り少ないカスタムコード)を使用してRecursiveArrayIterator、または失敗して、検索配列から親ツリーと一致するノードを返すにはどうすればよいですか?RecursiveIteratorIterator現在、この関数は8秒で14,000回実行されているため、可能な限り最速の関数を取得したいと考えています。したがって、組み込み関数を使用する必要があります。

私の既存の試み(以下)は信じられないほど遅いです。

function search_in_array($needle, $haystack) {
    $path = array();

    $it = new RecursiveArrayIterator($haystack);
    iterator_apply($it, 'traverse', array($it, $needle, &$path));

    return $path;
}

function traverse($it, $needle, &$path) {
    while($it->valid()) {
        $key = $it->key();
        $value = $it->current();

        if(strcasecmp($value['id'], $needle) === 0) {
            $path[] = $key;
            return;
        } else if($it->hasChildren()) {
            $sub = null;
            traverse($it->getChildren(), $needle, &$sub);
            if($sub) {
                $path[$key] = $sub;
            }
        }

        $it->next();
    }
}

の出力例は次の$needle = TVALLようになります。

Array (
    [HOMECINEMA] => Array (
        [children] => Array (
            [HC-VISION] => Array (
                [children] => Array (
                    [0] => TVALL
                )
            )
        )
    )
)

検索配列は次のようになります(広大さをお詫びします)。トップレベルのノードは3つ以上ありますが、簡潔にするために切り捨てています。

Array(2) (
    [HOMECINEMA] => Array (
        [id] => HOMECINEMA
        [position] => 2
        [title] => TV & Home Cinema
        [children] => Array (
            [HC-VISION] => Array (
                [id] => HC-VISION
                [title] => LCD & Plasma
                [children] => Array (
                    [TVALL] => Array (
                        [id] => TVALL
                        [title] => All TVs
                    )
                    [LCD2] => Array (
                        [id] => LCD2
                        [title] => LCD/LED TVs
                    )
                    [PLASMA] => Array (
                        [id] => PLASMA
                        [title] => Plasma TVs
                    )
                    [3DTV] => Array (
                        [id] => 3DTV
                        [title] => 3D TV
                    )
                    [LED] => Array (
                        [id] => LED
                        [title] => SMART TVs
                    )
                    [PROJECTORS] => Array (
                        [id] => PROJECTORS
                        [title] => Projectors
                    )
                    [SYS-HOMECINEMATV] => Array (
                        [id] => SYS-HOMECINEMATV
                        [title] => TV Home Cinema Systems
                    )
                )
            )
            [HC-SEPARATES] => Array (
                [id] => HC-SEPARATES
                [title] => Home Cinema Separates
                [children] => Array (
                    [DVDRECORDERS] => Array (
                        [id] => DVDRECORDERS
                        [title] => DVD Recorders
                    )
                    [HDDVD] => Array (
                        [id] => HDDVD
                        [title] => Blu-ray
                    )
                    [AVRECEIVERS] => Array (
                        [id] => AVRECEIVERS
                        [title] => AV Receivers
                    )
                    [DVDPLAYERS] => Array (
                        [id] => DVDPLAYERS
                        [title] => DVD Players
                    )
                    [FREEVIEW] => Array (
                        [id] => FREEVIEW
                        [title] => Digital Set Top Boxes
                    )
                    [DVDPACKAGESYSTEMS-3] => Array (
                        [id] => DVDPACKAGESYSTEMS-3
                        [title] => 1 Box Home Cinema Systems
                    )
                    [HOMECINEMADEALS] => Array (
                        [id] => HOMECINEMADEALS
                        [title] => Home Cinema System Deals
                    )
                )
            )
            [SPEAKER2] => Array (
                [id] => SPEAKER2
                [title] => Speakers
                [children] => Array (
                    [SPEAKERPACKAGES] => Array (
                        [id] => SPEAKERPACKAGES
                        [title] => Speaker packages
                    )
                    [SOUNDBARS] => Array (
                        [id] => SOUNDBARS
                        [title] => Soundbars
                    )
                    [CENTRES] => Array (
                        [id] => CENTRES
                        [title] => Centres
                    )
                    [SUBWOOFERS] => Array (
                        [id] => SUBWOOFERS
                        [title] => Subwoofers
                    )
                    [FLOORSTANDING] => Array (
                        [id] => FLOORSTANDING
                        [title] => Floorstanders
                    )
                    [INSTALLATIONSPEAKERS] => Array (
                        [id] => INSTALLATIONSPEAKERS
                        [title] => Installation Speakers
                    )
                    [STAND-MOUNT] => Array (
                        [id] => STAND-MOUNT
                        [title] => Bookshelf Speakers
                    )
                )
            )
            [HC-ACCYS] => Array (
                [id] => HC-ACCYS
                [title] => Accessories
                [children] => Array (
                    [AVESSENTIALS] => Array (
                        [id] => AVESSENTIALS
                        [title] => AV Interconnects
                    )
                    [PLASMALCDSTANDSBRACKETS1] => Array (
                        [id] => PLASMALCDSTANDSBRACKETS1
                        [title] => TV Accessories
                    )
                    [RACKS] => Array (
                        [id] => RACKS
                        [title] => TV Racks
                    )
                    [HIFIRACKS] => Array (
                        [id] => HIFIRACKS
                        [title] => HiFi Racks
                    )
                    [PROJECTORACCYS] => Array (
                        [id] => PROJECTORACCYS
                        [title] => Projector Screens/Accessories
                    )
                )
            )
        )
    )
    [SPEAKERS] => Array (
        [id] => SPEAKERS
        [position] => 3
        [title] => Speakers
        [children] => Array (
            [SPK-HIFI] => Array (
                [id] => SPK-HIFI
                [title] => Hi-Fi
                [children] => Array (
                    [STAND-MOUNT] => Array (
                        [id] => STAND-MOUNT
                        [title] => Bookshelf Speakers
                    )
                    [FLOORSTANDING] => Array (
                        [id] => FLOORSTANDING
                        [title] => Floorstanders
                    )
                    [INSTALLATIONSPEAKERS] => Array (
                        [id] => INSTALLATIONSPEAKERS
                        [title] => Installation Speakers
                    )
                )
            )
            [SPK-HOMECINEMA] => Array (
                [id] => SPK-HOMECINEMA
                [title] => Home Cinema
                [children] => Array (
                    [SPEAKERPACKAGES] => Array (
                        [id] => SPEAKERPACKAGES
                        [title] => Speaker Packages
                    )
                    [SOUNDBARS] => Array (
                        [id] => SOUNDBARS
                        [title] => Soundbars
                    )
                    [CENTRES] => Array (
                        [id] => CENTRES
                        [title] => Centres
                    )
                    [SUBWOOFERS] => Array (
                        [id] => SUBWOOFERS
                        [title] => Subwoofers
                    )
                )
            )
            [SPK-ACCYS] => Array (
                [id] => SPK-ACCYS
                [title] => Accessories
                [children] => Array (
                    [SPEAKERESSENTIALS1] => Array (
                        [id] => SPEAKERESSENTIALS
                        [title] => Speaker Cables
                    )
                    [SPEAKERSTANDS] => Array (
                        [id] => SPEAKERSTANDS
                        [title] => Speaker Stands
                    )
                    [SPEAKERBRACKETS] => Array (
                        [id] => SPEAKERBRACKETS
                        [title] => Speaker Wall Brackets
                    )
                )
            )
        )
    )
)
4

1 に答える 1

7

以下の例は、(時間またはメモリ要件の点で) 必ずしもよりパフォーマンスが高いとは限りませんが、構造を手動で再帰することを回避し、目的の出力配列を構築するためのより簡単な (IMHO) 方法を示しています。

function search_in_array($needle, $haystack) {
    $path = array();

    $it = new RecursiveIteratorIterator(
        new ParentIterator(new RecursiveArrayIterator($haystack)),
        RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($it as $key => $value) {
        if (array_key_exists('id', $value) && strcasecmp($value['id'], $needle) === 0) {
            $path = array($needle);
            for ($i = $it->getDepth() - 1; $i >= 0; $i--) {
                $path = array($it->getSubIterator($i)->key() => $path);
            }
            break;
        }
    }

    return $path;
}

参照

ボーナス

配列がさらに深くなる場合は、 RecursiveIteratorIterator::setMaxDepth()メソッドを使用して、再帰を深いレベルに制限することもできます。n

于 2012-11-29T21:54:49.163 に答える