Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中以树格式返回多维数组键?_Php_Arrays_Tree_Key_Multidimensional Array - Fatal编程技术网

如何在PHP中以树格式返回多维数组键?

如何在PHP中以树格式返回多维数组键?,php,arrays,tree,key,multidimensional-array,Php,Arrays,Tree,Key,Multidimensional Array,如何在PHP中以树格式返回多维数组键 例如,如果我有以下数组: $array = array ( array ( 'name' => 'A', 'product' => array ( 'qty' => 1, 'brand' => 'Tim' ), 'goods' => array ( 'qty' => 2

如何在PHP中以树格式返回多维数组键

例如,如果我有以下数组:

$array = array ( 
    array (
        'name' => 'A', 
        'product' => array (
            'qty' => 1,
            'brand' => 'Tim'
        ), 
        'goods' => array (
            'qty' => 2
        ), 
        'brand' => 'Lin'
    ),
    array (
        'name' => 'B', 
        'product' => array (
            'qty' => 6,
            'brand' => 'Coff'
        ),
        'goods' => array (
            'qty' => 4
        ), 
        'brand' => 'Ji'
    )
);
如何获得如下结果--包括不重复键:

-name
-product
--qty
--brand
-goods
--qty
--brand

对于无限深度,您需要一个递归函数。我想你有$name中的父母和$children中的孩子:

function render_select($root=0, $level=-1) 
{
    global $names, $children;
    if ($root != 0)
       echo '<option>' . strrep(' ', $level) . $names[$root] . '</option>';
    foreach ($children[$root] as $child)
       render_select($child, $level+1);
}
function render\u select($root=0,$level=-1)
{
全球$姓名,$儿童;
如果($root!=0)
回显“”。strrep(“”,$level)。$names[$root].';
foreach($children[$root]作为$child)
渲染_选择($child,$level+1);
}

此函数非常有用,因为可以为其提供两个变量。另一个Answare需要一个多维数组。

如果深度不受限制,则需要一个递归函数。我想你有$name中的父母和$children中的孩子:

function render_select($root=0, $level=-1) 
{
    global $names, $children;
    if ($root != 0)
       echo '<option>' . strrep(' ', $level) . $names[$root] . '</option>';
    foreach ($children[$root] as $child)
       render_select($child, $level+1);
}
function render\u select($root=0,$level=-1)
{
全球$姓名,$儿童;
如果($root!=0)
回显“”。strrep(“”,$level)。$names[$root].';
foreach($children[$root]作为$child)
渲染_选择($child,$level+1);
}

此函数非常有用,因为可以为其提供两个变量。另一个Answare需要一个多维数组。

递归函数应该覆盖您想要/需要的任何深度:

 function print_tree($tree, $level = 0) {
     foreach($tree AS $name => $node) {
         if(
               is_scalar($node) OR
               (
                   is_object($node) AND
                   method_exists($node, '__toString')
               )
           ) {
             echo str_repeat('-', $level).$name.': '.$node;
         }
         else if(
                   is_array($node) OR
                   (
                       is_object($node) AND
                       $node InstanceOf Traversable
                   )
                ) {
             echo str_repeat('-', $level).$name.":\n";
             print_tree($node, $level+1);
         }
     }
 }

递归函数应涵盖您想要/需要的任何深度:

 function print_tree($tree, $level = 0) {
     foreach($tree AS $name => $node) {
         if(
               is_scalar($node) OR
               (
                   is_object($node) AND
                   method_exists($node, '__toString')
               )
           ) {
             echo str_repeat('-', $level).$name.': '.$node;
         }
         else if(
                   is_array($node) OR
                   (
                       is_object($node) AND
                       $node InstanceOf Traversable
                   )
                ) {
             echo str_repeat('-', $level).$name.":\n";
             print_tree($node, $level+1);
         }
     }
 }


看来你赢了我。但是,您可能希望打印非标量值的字符串表示形式。我添加了可用于字符串的对象和可用于数组的对象的额外检查。类似于[X类的对象]的sprint对于没有_utoString方法的对象很有用。和资源。迭代器扩展了traversable,所以不需要包含它。另外,刚刚实现ArrayAccess的对象不能使用foreach进行遍历。我认为traversable只由内部使用。首先,我不同意打印[object ClassName]更好,因为我们没有创建打印/var\u转储分析函数,只是一个树打印机,用于在树中有例如类别之类的情况。看起来你比我快了。但是,您可能希望打印非标量值的字符串表示形式。我添加了可用于字符串的对象和可用于数组的对象的额外检查。类似于[X类的对象]的sprint对于没有_utoString方法的对象很有用。和资源。迭代器扩展了traversable,所以不需要包含它。另外,刚刚实现ArrayAccess的对象不能使用foreach进行遍历。我认为traversable只由内部使用。首先,我不同意打印[object ClassName]更好,因为我们没有创建打印/var\u转储分析函数,只需一个树打印机,用于在树中有例如类别之类的情况。您应该首先检查值
是否为_scalar
,因为它更可能是一个标量,并且与测试它是否为数组/对象相比,检查它是否为标量花费的时间更少。IMO,打印非数组和非标量值的字符串表示形式比完全忽略它们更可取。这是真的,但不能打印没有_-toString方法的对象,可以吗?因此,您应该检查以确保。请参阅我对您答案的评论。您应该首先检查值
是否为_scalar
,因为它更可能是一个标量,并且与测试它是否为数组/对象相比,检查它是否为标量花费的时间更少。IMO,打印非数组和非标量值的字符串表示形式比完全忽略它们更可取。这是真的,但不能打印没有_-toString方法的对象,可以吗?所以你应该检查确认。请看我对你答案的评论。等等,你只想打印没有值的键?等等,你只想打印没有值的键?函数中的全局变量是糟糕的设计和糟糕的实践。它们依赖于全局范围内变量的名称,并使函数不可移植
global
$GLOBALS
很像
goto
——仅仅因为它们在那里,并不意味着你应该使用它们。这条规则很少有例外,但这不是其中之一。Typo3使用了很多全局变量。你能说常量比全局变量更好吗?函数式编程语言和面向对象编程语言“修复”的大多数问题都与封装数据有关,并且有一个清晰的路径,即“数据来自何处”、“上次修改的地方”、“如何修改”。程序代码的缺点是,通过使用
global
goto
,您可能会意外地得到在您希望全局变量保持其状态时更改全局变量的结果。因此,应用程序的行为会发生变化。常量是
constant
globals是
global
,您无法将苹果与橙子进行比较。常量与变量不同,因为它们包含常量(从不改变)标量值。对于这样的作业,您希望将数组传递给函数,并使一个参数通过递归来跟踪当前深度。函数中的全局变量是糟糕的设计和糟糕的实践。它们依赖于全局范围内变量的名称,并使函数不可移植
global
$GLOBALS
很像
goto
——仅仅因为它们在那里,并不意味着你应该使用它们。这条规则很少有例外,但这不是其中之一。Typo3使用了很多全局变量。你能说常量比全局变量更好吗?函数式编程语言和面向对象编程语言“修复”的大多数问题都与封装数据有关,并且有一个清晰的路径,即“数据来自何处”、“上次修改的地方”、“如何修改”。程序代码的缺点是