簡體   English   中英

PHP:將具有path屬性的數組轉換為樹結構

[英]PHP: Convert an array with a path attribute to a tree structure

可以說,我有以下數組:

$array = array(
    array(
        "id"   => 1,
        "name" => "Europe",
        "path" => "/"
    ),
    array(
        "id"   => 2,
        "name" => "Germany",
        "path" => "/1/"
    ),
    array(
        "id"   => 3,
        "name" => "France",
        "path" => "/1/"
    ),
    array(
        "id"   => 4,
        "name" => "Berlin",
        "path" => "/1/2/"
    ),
    array(
        "id"   => 5,
        "name" => "Munich",
        "path" => "/1/2/"
    )
);

如您所見,它是一個多維數組,在earch 2級數組中具有3個屬性:id,名稱和路徑。 該路徑是基於其父代的parent-id的路徑結構。 例如,德國(id = 2)屬於歐洲,因此路徑為“ / 1 /”(ID 1 =歐洲),德國柏林的路徑為“ / 1/2 /”,表示“ / Europe / Germany /“

現在,我正在嘗試以此創建一個樹形數組,它看起來應該像這樣:

$result = array(
    1 => array(
        "id" => 1,
        "name" => "Europe",
        "path" => "/",
        "childs" => array(
            2 => array(
                "id" => 2,
                "name" => "Germany",
                "path" => "/1/",
                "childs" => array(
                    4 => array(
                        "id"   => 4,
                        "name" => "Berlin",
                        "path" => "/1/2/"
                    ),
                    5 => array(
                        "id"   => 5,
                        "name" => "Munich",
                        "path" => "/1/2/"
                    )
                )
            ),
            3 => array(
                "id"   => 3,
                "name" => "France",
                "path" => "/1/"
            )
        )
    )
);

我已經嘗試用內部引用創建一個函數,但這對我不起作用:

public static function pathToTree($items) {
    $array = array();
    $result = array();

    foreach($items AS $res) {
        $ids = explode("/", ltrim($res["path"] . $res["id"], "/"));
        $count = count($ids);
        $tmp = &$result;

        foreach( $ids AS $id) {
            if($count == 1) {
                $tmp = $res;
                $tmp["childs"] = array();
                $tmp = &$tmp["childs"];
            }
            else {
                $tmp[$id] = array(
                    "childs" => array()
                );
                $tmp = &$tmp[$id]["childs"];
            }
            $count--;
        }
    }

    return $array;
}

好的,我想我剛剛找到了一個解決方案:

function pathToTree($array){
    $tree = array();
    foreach($array AS $item) {
        $pathIds = explode("/", ltrim($item["path"], "/") . $item["id"]);
        $current = &$tree;
        foreach($pathIds AS $id) {
            if(!isset($current["childs"][$id])) $current["childs"][$id] = array();
            $current = &$current["childs"][$id];
            if($id == $item["id"]) {
                $current = $item;
            }
        }
    }
    return $tree["childs"];
}

這是針對1-n深度的動力學解決方案。 http://ideone.com/gn0XLp上查看我的示例。 在這里,我在一定程度上進行了測試:

  1. 大陸
  2. 國家
  3. 市轄區
  4. 市區
  5. 城市分區

正如我在評論中所說,您至少需要三個循環才能實現目標。 功能如下:

function pathToTree($array){
    $tree = Array();
    for($i=0; $i < count($array); $i++){
        if(substr_count($array[$i]["path"], '/') == 1)
            $tree[$array[$i]["id"]] = $array[$i];
    }
    for($i=0; $i < count($array); $i++){
        if(substr_count($array[$i]["path"], '/') == 2){
            $num = (int)str_replace("/","",$array[$i]["path"]);
            $tree[$num]["childs"][$array[$i]["id"]] = $array[$i];
        }
    }
    for($i=0; $i < count($array); $i++){
        if(substr_count($array[$i]["path"], '/') == 3){
            $num = explode("/", $array[$i]["path"]);
            $tree[$num[1]]["childs"][$num[2]]["childs"][$array[$i]["id"]] = $array[$i];
        }
    }
    return $tree;
}

例:

考慮以下數組:

$array = array(
    array(
        "id"   => 1,
        "name" => "Europe",
        "path" => "/"
    ),
    array(
        "id"   => 2,
        "name" => "Germany",
        "path" => "/1/"
    ),
    array(
        "id"   => 3,
        "name" => "France",
        "path" => "/1/"
    ),
    array(
        "id"   => 4,
        "name" => "Berlin",
        "path" => "/1/2/"
    ),
    array(
        "id"   => 5,
        "name" => "Munich",
        "path" => "/1/2/"
    ),
    array(
        "id"   => 6,
        "name" => "Asia",
        "path" => "/"
    ),
    array(
        "id"   => 7,
        "name" => "China",
        "path" => "/6/"
    ),
    array(
        "id"   => 8,
        "name" => "Bangladesh",
        "path" => "/6/"
    ),
    array(
        "id"   => 9,
        "name" => "Beijing",
        "path" => "/6/7/"
    ),
    array(
        "id"   => 10,
        "name" => "Dhaka",
        "path" => "/6/8/"
    )
);

如果我運行此代碼:

print_r(pathToTree($array));

輸出將是:

Array
(
    [1] => Array
        (
            [id] => 1
            [name] => Europe
            [path] => /
            [childs] => Array
                (
                    [2] => Array
                        (
                            [id] => 2
                            [name] => Germany
                            [path] => /1/
                            [childs] => Array
                                (
                                    [4] => Array
                                        (
                                            [id] => 4
                                            [name] => Berlin
                                            [path] => /1/2/
                                        )

                                    [5] => Array
                                        (
                                            [id] => 5
                                            [name] => Munich
                                            [path] => /1/2/
                                        )

                                )

                        )

                    [3] => Array
                        (
                            [id] => 3
                            [name] => France
                            [path] => /1/
                        )

                )

        )

    [6] => Array
        (
            [id] => 6
            [name] => Asia
            [path] => /
            [childs] => Array
                (
                    [7] => Array
                        (
                            [id] => 7
                            [name] => China
                            [path] => /6/
                            [childs] => Array
                                (
                                    [9] => Array
                                        (
                                            [id] => 9
                                            [name] => Beijing
                                            [path] => /6/7/
                                        )

                                )

                        )

                    [8] => Array
                        (
                            [id] => 8
                            [name] => Bangladesh
                            [path] => /6/
                            [childs] => Array
                                (
                                    [10] => Array
                                        (
                                            [id] => 10
                                            [name] => Dhaka
                                            [path] => /6/8/
                                        )

                                )

                        )

                )

        )

)

這是phpfiddle鏈接 ,以防您自己嘗試。

我創建了一個遞歸函數:

//數組

$array = array(
    array(
        "id"   => 1,
        "name" => "Europe",
        "path" => "/"
    ),
    array(
        "id"   => 2,
        "name" => "Germany",
        "path" => "/1/"
    ),
    array(
        "id"   => 3,
        "name" => "France",
        "path" => "/1/"
    ),
    array(
        "id"   => 4,
        "name" => "Berlin",
        "path" => "/1/2/"
    ),
    array(
        "id"   => 5,
        "name" => "Munich",
        "path" => "/1/2/"
    ),
    array(
        "id"   => 6,
        "name" => "Asia",
        "path" => "/"
    ),
    array(
        "id"   => 7,
        "name" => "India",
        "path" => "/6/"
    ),
    array(
        "id"   => 7,
        "name" => "Mumbai",
        "path" => "/6/7"
    ),
    array(
        "id"   => 8,
        "name" => "Delhi",
        "path" => "/6/7"
    ),
);

//遞歸函數

function createTree($input, &$result = array(), $key = null) {
    if ($key == "id") {
        $result["temp"]["id"] = $input;
    }
    if ($key == "name") {
        $result["temp"]["name"] = $input;
    }
    if ($key == "path") {
        $result["temp"]["path"] = $input;
        $levels = is_string($input) ? array_values(array_filter(explode('/', $input))) : null;
        if ($input == "/") {
            $result[$result["temp"]["id"]] = $result["temp"];
        }
        if (count($levels) == 1) {
            $result[$levels[0]]["childs"][$result["temp"]["id"]] = $result["temp"];
        }
        if (count($levels) == 2) {
            $result[$levels[0]]["childs"][$levels[1]]["childs"][$result["temp"]["id"]] = $result["temp"];
        }
        unset($result["temp"]);
    }
    if (is_array($input)) {
        foreach($input as $key => $value) {
            createTree($value, $result, $key);
        }
    }
    return $result;
}

// 結果

array (
  1 => 
  array (
    'id' => 1,
    'name' => 'Europe',
    'path' => '/',
    'childs' => 
    array (
      2 => 
      array (
        'id' => 2,
        'name' => 'Germany',
        'path' => '/1/',
        'childs' => 
        array (
          4 => 
          array (
            'id' => 4,
            'name' => 'Berlin',
            'path' => '/1/2/',
          ),
          5 => 
          array (
            'id' => 5,
            'name' => 'Munich',
            'path' => '/1/2/',
          ),
        ),
      ),
      3 => 
      array (
        'id' => 3,
        'name' => 'France',
        'path' => '/1/',
      ),
    ),
  ),
  6 => 
  array (
    'id' => 6,
    'name' => 'Asia',
    'path' => '/',
    'childs' => 
    array (
      7 => 
      array (
        'id' => 7,
        'name' => 'India',
        'path' => '/6/',
        'childs' => 
        array (
          7 => 
          array (
            'id' => 7,
            'name' => 'Mumbai',
            'path' => '/6/7',
          ),
          8 => 
          array (
            'id' => 8,
            'name' => 'Delhi',
            'path' => '/6/7',
          ),
        ),
      ),
    ),
  ),
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM