-1

我需要帮助。我正在寻找解决这个问题的方法!我有一个包含以下模式的文件:

巴西|圣保罗|Diadema|RuadaFe 巴西|SaoPaulo|Diadema|RuadoLimoeiro Brazil|SaoPaulo|SaoCaetano|RuadasLaranjeiras Brazil|Parana|Curitiba|Comendador Araujo USA|NewJersey|JerseyCity|WashingtonBoulvard USA|NewJersey|JerseyCity|RiverCourt

在一些数组键实现之后应该会带来类似这样的东西(在 php 上应用 json_encode 调用之后):

{
    "name": "Brazil",
    "children": [
    {
        "name": "SaoPaulo",
        "children": [
            {
                "name": "Diadema",
                "children": [
                    {"name": "RuadaFe"},
                    {"name": "RuadoLimoeiro"}
                ]
            },
            {
                "name": "SaoCaetano",
                "children": [
                    {"name": "RuadasLaranjeiras"}
                ]
            },
        ]
        "name": "Parana",
        "children": [
            {
                "name": "Curitiba",
                "children": [
                    {"name": "ComendadorAraujo"}
                ]
            }
       ]
    },
    "name":"USA",
    "children":[
      {
         "name": "NewJersey",
          "children": [
            {
                "name": "JerseyCity",
                "children": [
                    {"name": "WhashingonBoulevard"},
                    {"name": "RiverCourt"}
                ]
            }
          ]
       }
     ]
  }
 ]

并继续前进(甚至更深入)。请帮助我的团队...在此先感谢。

到现在为止我得到的是:

数组 ( [巴西] => 数组 ( [圣保罗] => 数组 ( [Diadema] => 数组 ( [RuadoLimoeiro] => )

                [SaoCaetano] => Array
                    (
                        [RuadasLaranjeiras] => 
                    )

            )

        [Parana] => Array
            (
                [Curitiba] => Array
                    (
                        [ComendadorAraujo] => 
                    )

            )

    )

[USA] => Array
    (
        [NewJersey] => Array
            (
                [JerseyCity] => Array
                    (
                        [WhashingtonBoulervard] => 
                        [RiverCourt] => 
                    )

            )

    )

)

这是 json 编码:

{
"Brazil":{
"SaoPaulo":
   {"Diadema":
       {"RuadoLimoeiro":null},
       "SaoCaetano":{"RuadasLaranjeiras":null}
       },
"Parana":
   {"Curitiba":
       {"ComendadorAraujo":null}
   }
},
"USA":{
"NewJersey":{
"JerseyCity":{
     "WhashingtonBoulervard":null,
     "RiverCourt":null}
      }
    }
}

如您所见,缺少“名称”和“孩子”是因为不是数组键结构,也有问题,因为我在圣保罗缺少一些值。

这是功能:

foreach($strings as $string) {
    $parts = array_filter(explode('|', $string));
    $ref = &$result;
    foreach($parts as $p) {
       // echo $p;
        if(!isset($ref[$p])) {
            $ref[$p] = array();
           // $ref[$p] = array("name"=>$p);
        }

        $ref = &$ref[$p];

    }
    $ref = null;
}

-------------------------------- 在一些答案之后 --------------- ------------

{
    "name": "Brazil(country)",
    "children": [
    {
        "name": "SaoPaulo(state)", // only one state
        "children": [
            {
                "name": "Diadema(city)", // only one city
                "children": [
                    {"name": "RuadaFe(street)"}, // two streets under the same city...
                    {"name": "RuadoLimoeiro(street)"}
                ]
            },
            {
                "name": "SaoCaetano(city)",
                "children": [
                    {"name": "RuadasLaranjeiras(street)"}
                ]
            },
        ]
        "name": "Parana(state)",
        "children": [
            {
                "name": "Curitiba(city)",
                "children": [
                    {"name": "ComendadorAraujo(street)"}
                ]
            }
       ]
    },...

我把结构(国家,州,城市,街道)放在父母身上,只是为了澄清我想要的东西。知道了?

4

2 回答 2

0

它解决了你的问题吗?用于$inputString放置您的真实字符串。

    <?php

// ------------------------------------------------------ your input goes here ------------------------------------------------------
$inputString = 'Brazil|SaoPaulo|Diadema|RuadaFe Brazil|SaoPaulo|Diadema|RuadoLimoeiro Brazil|SaoPaulo|SaoCaetano|RuadasLaranjeiras Brazil|Parana|Curitiba|ComendadorAraujo USA|NewJersey|JerseyCity|WhashingtonBoulervard USA|NewJersey|JerseyCity|RiverCourt';

class item {
    public $name = null;

    public function getChildrenByName($strName) {

        $ret = null;
        # this variable should be defined in interface, but i skipped it so it wont be printed in json when obj does not have childrens
        if( !isset( $this->children ) ) {
            $this->children = array(  );
        }

        foreach ( $this->children as $child ) {
            if( $child->name === $strName ) {
                $ret = $child;
                break;
            }
        }


        if ( !$ret ) {
            $this->children[] = self::spawnByName( $strName );
        }

        return $this->children[ count($this->children) - 1];
    }

    static public function spawnByName($strName) {
        $ret = new item();
        $ret->name = $strName;
        return $ret;
    }
}

class listManager {

    protected $list = array();

    public function getList() {
        return $this->list;
    }

    public function addPath( $desiredPath ) {

        # path needs to be as array
        if ( is_string( $desiredPath ) ) {
            $desiredPath = explode('|', $desiredPath);
        }

        # create root element if it does not already exists
        if ( !isset( $this->list[$desiredPath[0]] ) ) {
            $this->list[$desiredPath[0]] = item::spawnByName($desiredPath[0]);
        }

        $curElement = $this->list[$desiredPath[0]];

        for( $i=1; $i<count($desiredPath); $i++ ) {
            $curElement = $curElement->getChildrenByName( $desiredPath[$i] );
        }

    }

    protected function spawnElement( $strName ) {
        $ret = new item();
        $ret->name = $strName;
        return $ret;
    }
}

$output = array();
$expl = explode(' ', $inputString);
$list = new listManager();

foreach ( $expl as $key => $path ) {
    $list->addPath( $path );

}

$output = '';

foreach ( $list->getList() as $singleVariable ) {
    $output .= json_encode($singleVariable, JSON_PRETTY_PRINT) . ",\n";
}

echo '<pre>'.$output.'</pre>';

?>

上面的代码从您的示例代码中生成以下 json:

{
    "name": "Brazil",
    "children": [{
            "name": "SaoPaulo",
            "children": [{
                    "name": "Diadema",
                    "children": [{
                            "name": "RuadaFe"
                        }
                    ]
                }
            ]
        }, {
            "name": "SaoPaulo",
            "children": [{
                    "name": "Diadema",
                    "children": [{
                            "name": "RuadoLimoeiro"
                        }
                    ]
                }
            ]
        }, {
            "name": "SaoPaulo",
            "children": [{
                    "name": "SaoCaetano",
                    "children": [{
                            "name": "RuadasLaranjeiras"
                        }
                    ]
                }
            ]
        }, {
            "name": "Parana",
            "children": [{
                    "name": "Curitiba",
                    "children": [{
                            "name": "ComendadorAraujo"
                        }
                    ]
                }
            ]
        }
    ]
} {
    "name": "USA",
    "children": [{
            "name": "NewJersey",
            "children": [{
                    "name": "JerseyCity",
                    "children": [{
                            "name": "WhashingtonBoulervard"
                        }
                    ]
                }
            ]
        }, {
            "name": "NewJersey",
            "children": [{
                    "name": "JerseyCity",
                    "children": [{
                            "name": "RiverCourt"
                        }
                    ]
                }
            ]
        }
    ]
}

编辑:改变了,现在适合吗?

于 2013-04-30T16:50:26.047 回答
0

这并非微不足道,但我所做的实际上与您相同(与您编辑的问题中的方式相同),但我也跟踪这些数组以重命名键。这就是我之后所做的:

$separator = [' ', '|'];

$buffer = file_get_contents($file);
$entries = explode($separator[0], $buffer);
$result = [];
$named[] = &$result;
########
foreach ($entries as $entry) {
    $each     = explode($separator[1], $entry);
    $pointer  = & $result;
    while ($current = array_shift($each)) {
        if (!isset($pointer[$current])) {
            unset($children);
            $children = [];
            $named[] = &$children;
            ########
            $pointer[$current] = ['name' => $current, 'children' => &$children];
        }
        $pointer = & $pointer[$current]['children'];
    }
}

foreach($named as $offset => $namedArray) {
    $keys = array_keys($namedArray);
    foreach($keys as $key) {
        $named[$offset][] = &$namedArray[$key];
        unset($named[$offset][$key]);
    }
}

print_r($result);

在行动中看到它。

如果子节点为空(叶节点),您可能希望通过检查稍后的 foreach 来修改它,然后也删除子条目。

这里是最后修改的foreach和json输出:

foreach($named as $offset => $namedArray) {
    $keys = array_keys($namedArray);
    foreach($keys as $key) {
        if (!$namedArray[$key]['children']) {
            unset($namedArray[$key]['children']);
        }
        $named[$offset][] = &$namedArray[$key];
        unset($named[$offset][$key]);
    }
}

echo json_encode($result, JSON_PRETTY_PRINT);

输出:

[
    {
        "name": "Brazil",
        "children": [
            {
                "name": "SaoPaulo",
                "children": [
                    {
                        "name": "Diadema",
                        "children": [
                            {
                                "name": "RuadaFe"
                            },
                            {
                                "name": "RuadoLimoeiro"
                            }
                        ]
                    },
                    {
                        "name": "SaoCaetano",
                        "children": [
                            {
                                "name": "RuadasLaranjeiras"
                            }
                        ]
                    }
                ]
            },
            {
                "name": "Parana",
                "children": [
                    {
                        "name": "Curitiba",
                        "children": [
                            {
                                "name": "ComendadorAraujo"
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "name": "USA",
        "children": [
            {
                "name": "NewJersey",
                "children": [
                    {
                        "name": "JerseyCity",
                        "children": [
                            {
                                "name": "WhashingtonBoulervard"
                            },
                            {
                                "name": "RiverCourt"
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

完整的代码示例一目了然:

<?php
/**
 * PHP - Nested array keys based on string lines
 * @link http://stackoverflow.com/a/16305236/2261774
 */
$file = 'data://text/plain;base64,' . base64_encode('Brazil|SaoPaulo|Diadema|RuadaFe Brazil|SaoPaulo|Diadema|RuadoLimoeiro Brazil|SaoPaulo|SaoCaetano|RuadasLaranjeiras Brazil|Parana|Curitiba|ComendadorAraujo USA|NewJersey|JerseyCity|WhashingtonBoulervard USA|NewJersey|JerseyCity|RiverCourt');

$separator = [' ', '|'];

$buffer = file_get_contents($file);
$entries = explode($separator[0], $buffer);
$result = [];
$named[] = &$result;
foreach ($entries as $entry) {
    $each     = explode($separator[1], $entry);
    $pointer  = & $result;
    while ($current = array_shift($each)) {
        if (!isset($pointer[$current])) {
            unset($children);
            $children = [];
            $named[] = &$children;
            $pointer[$current] = ['name' => $current, 'children' => &$children];
        }
        $pointer = & $pointer[$current]['children'];
    }
}
unset($pointer);

foreach($named as $offset => $namedArray) {
    $keys = array_keys($namedArray);
    foreach($keys as $key) {
        if (!$namedArray[$key]['children']) {
            unset($namedArray[$key]['children']);
        }
        $named[$offset][] = &$namedArray[$key];
        unset($named[$offset][$key]);
    }
}
unset($named);

echo json_encode($result, JSON_PRETTY_PRINT);

你的问题 JSON:

{
    "name": "Brazil",
    "children": [
    {
        "name": "SaoPaulo",
        "children": [
            {
                "name": "Diadema",
                "children": [
                    {"name": "RuadaFe"},
                    {"name": "RuadoLimoeiro"}
                ]
            },

我的答案 JSON:

[
    {
        "name": "Brazil",
        "children": [
            {
                "name": "SaoPaulo",
                "children": [
                    {
                        "name": "Diadema",
                        "children": [
                            {
                                "name": "RuadaFe"
                            },
                            {
                                "name": "RuadoLimoeiro"
                            }
                        ]
                    },

我能发现的唯一区别是根节点在我的答案中被包装在一个数组中,但是如果这确实是您的问题,那么将它们取出应该是微不足道的;)

于 2013-04-30T16:59:50.417 回答