まおさんの備忘録

会社やら家やらで調べた事に関する備忘録

経路列挙モデルのデータを配列化する

PHPのarray_mergeの仕様により苦しめられたり

そもそもそのロジックに行き当たるまでに1時間は頭を悩ませていたという経緯から

ちゃんとログに残そうかと。

経路列挙モデルというのはDBの話で

親子関係をPath形式で所持する方法。(だと思ってるw

経路列挙モデル(検索編):MySQLで階層化データを使う | MAKIZOU.COM

ここら辺がわかりやすい感じ。

これを、PHPで扱う時

どうやって再帰的に処理を行うかで頭をすごく悩ませた本日の午前中。

なんとか形になったので、忘れないうちにログに残します。

    function pathToArray(){

        $path = ".1.2.5.";

        $rows = array(
            array("id" => 1 , "path" => ".1.","name"=>"name1"),
            array("id" => 2 , "path" => ".1.2.","name"=>"name2"),
            array("id" => 5 , "path" => ".1.2.5.","name"=>"name5"),
            array("id" => 6 , "path" => ".1.6.","name"=>"name6"),

        );

        $result  = array();

        foreach($rows as $row){
            $path = $row["path"];
            $temp = explode(".",$path);
            $temp = array_filter($temp);

            $prev["row"] = $row;//配列最初のキー取得

            foreach(array_reverse ($temp)  as $tempS){
                $res["$tempS"] = $prev;
                $prev = array();
                $prev["ID$tempS"] =$res["$tempS"];//array_mergeの仕様で数値型になると再振り分けしちゃうので文字列型に無理矢理w
            }

            if(count($result) != 0){
                $result = array_merge_recursive($result,$prev);
            }else{
                $result = $prev;
            }

            $prev = array();
        }


        var_dump($result);

    }

これを実行すると

array (size=1)
  'ID1' => 
    array (size=3)
      'row' => 
        array (size=3)
          'id' => int 1
          'path' => string '.1.' (length=3)
          'name' => string 'name1' (length=5)
      'ID2' => 
        array (size=2)
          'row' => 
            array (size=3)
              'id' => int 2
              'path' => string '.1.2.' (length=5)
              'name' => string 'name2' (length=5)
          'ID5' => 
            array (size=1)
              'row' => 
                array (size=3)
                  'id' => int 5
                  'path' => string '.1.2.5.' (length=7)
                  'name' => string 'name5' (length=5)
      'ID6' => 
        array (size=1)
          'row' => 
            array (size=3)
              'id' => int 6
              'path' => string '.1.6.' (length=5)
              'name' => string 'name6' (length=5)

こうなるので、rowがあったら処理をして
なければ処理しない的な再帰的なものを作ってあげれば
Pathの順序にいろいろとできるよっていう。

いやー頭を痛ませました。

(はてぶろのソース記法についても一瞬悩まされましたよ。。。orz

変数名がアレなのはつっこまないでください。。。