PHP递归练习构建数组

时间:2018-03-17 20:25:44

标签: php recursion

[
    'one/two' => 3,
    'one/four/0' => 5,
    'one/four/1' => 6,
    'one/four/2' => 7,
    'eight/nine/ten' => 11
]

我正在尝试基于$ json_str构建上面的数组:

$json_str = '{
    "one":
    {
        "two": 3,
        "four": [ 5,6,7]
    },
    "eight":
    {
        "nine":
        {
            "ten":11
        }
    }
}';

我构建了一个递归函数,通过这个$ json_str循环,但到目前为止我只能输出字符串。

如何构建数组而不是回显字符串?

另外,我如何只获得属于关联索引的索引值。

目前我只能获得所有要打印的密钥:

one/two => 3

one/two/four/0 => 5

one/two/four/0/1 => 6

one/two/four/0/1/2 => 7

one/eight/nine/ten => 11

以下是我到目前为止:

<?php

function printAll($a, $prefix = '') {

  if (!is_array($a) && !is_object($a)) {

    $prefix = rtrim($prefix, '/');

    echo $prefix . ' => ' . $a, "\n";

    return;
  }

  foreach($a as $k => $v) {

    $prefix .= $k . "/";

    printAll($v, $prefix);
  }
}


$json_str = '{
                "one":
                {
                    "two": 3,
                    "four": [ 5,6,7]
                },
                "eight":
                {
                    "nine":
                    {
                        "ten":11
                    }
                }
            }';


$object = json_decode($json_str);
printAll($object);

2 个答案:

答案 0 :(得分:3)

您可以使用数组来保存对象的键,而不是使用字符串,并使用array_pop()删除循环结束时的最后一个键。所以你有一个堆栈的密钥,可以用来获取JSON数据的痕迹。

function printAll(&$out = [], $a, $prefix = []) {
    foreach ($a as $key => $value) {
        $prefix[] = $key;  // add the key to "prefix"
        if (is_array($value) || is_object($value)) {
            printAll($out, $value, $prefix);
        }else{
            $out[implode('/', $prefix)] = $value;
        }
        // remove current key because we are no more inside it.
        array_pop($prefix);
    }
}

$json_str = '{"one": {"two": 3, "four": [ 5,6,7] }, "eight": {"nine": {"ten":11 } } }';

$object = json_decode($json_str);
$data = [];
printAll($data, $object);
print_r($data);

输出:

Array
(
    [one/two] => 3
    [one/four/0] => 5
    [one/four/1] => 6
    [one/four/2] => 7
    [eight/nine/ten] => 11
)

答案 1 :(得分:1)

您在foreach循环中修改$prefix。因此,在循环的每个后续迭代中都会有变化。如果将输出缓存在临时变量中,则应该没问题:

foreach($a as $k => $v) {
    $tmp = $prefix;
    $tmp .= $k . "/";
    printAll($v, $tmp);
}

现在,如果你想构建一个数组而不是回显你可以简单地通过引用传递数组,并构建它:

function printAll($a, &$output, $prefix = '') {
  if (!is_array($a) && !is_object($a)) {
    $prefix = rtrim($prefix, '/');
    $output[]= $prefix . ' => ' . $a. "\n";
    return;
  }
  foreach($a as $k => $v) {
    $tmp = $prefix;
    $tmp .= $k . "/";
    printAll($v, $output, $tmp);
  }
}

我在这里放了一个演示:https://3v4l.org/LSvZN