-1

助けが必要です。この問題の解決策を探しています!次のパターンを含むファイルがあります。

ブラジル|サンパウロ|ディアデマ|ルアダフェ ブラジル|サンパウロ|ディアデマ|ルアドリモエイロ ブラジル|サンパウロ|サンカエターノ|ルアダスラランジェイラス ブラジル|パラナ|クリチバ|コメンダドールアラウーホ 米国|ニュージャージー|ジャージーシティ|ワシントンブルバード 米国|ニュージャージー|ジャージーシティ|リバーコート

これは、配列キーの実装の後に、次のようなものをもたらすはずです(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"}
                ]
            }
          ]
       }
     ]
  }
 ]

そして、どんどん進んでください(そしてさらに深く)。チームを助けてください...よろしくお願いします。

ここで私が今まで得たもの:

Array ( [Brazil] => Array ( [SaoPaulo] => Array ( [Diadema] => Array ( [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}
      }
    }
}

ご覧のとおり、「names」と「child」は配列キー構造ではないため欠落しています。また、SaoPaulo でいくつかの値が欠落しているため、何かが間違っています。

関数は次のとおりです。

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

それはまったく些細なことではありませんが、私がやったことは実際にはあなたと同じです(編集した質問と同じ方法です)が、キーの名前を変更するためにそれらの配列も追跡します。そして、それは私がその後行うことです:

$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 に答える
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 に答える