代码之家  ›  专栏  ›  技术社区  ›  Calvin

操纵多维数组的结构

  •  0
  • Calvin  · 技术社区  · 17 年前

    这实际上是一个我已经解决的问题,但我怀疑可能有更好的解决方案。我有一个嵌套数组,它基本上表示类别树中所有节点的列表(没有特定顺序):

    Array(
        [0] => Array(
            [Category] => Array(
                [id] => 49
                [name] => Poster
            )
            [Child] => Array()
        )
        [1] => Array(
            [Category] => Array(
                [id] => 48
                [name] => Sticker
            )
            [Child] => Array()
        )
        [2] => Array(
            [Category] => Array(
                [id] => 46
                [name] => Hat
            )
            [Child] => Array()
        )
        [3] => Array(
            [Category] => Array(
                [id] => 45
                [name] => Hoodie
            )
            [Child] => Array()
        )
    )
    

    $node['Child'] 在所有实例中都是空数组。这是因为我已经用过了 array_filter() 以过滤掉所有非叶节点。尽管如此,我最终还是希望有一个一维叶节点数组,如下所示:

    Array(
        [49] => Poster
        [48] => Sticker
        [46] => Hat
        [45] => Hoodie
    )
    

    那么,将第一个数组转换为第二个数组的最优雅方式是什么呢?

    (可选)也可以从叶节点和非叶节点的数组开始,尝试修剪数组并重新构造它。非叶节点的示例如下:

    [7] => Array(
        [Category] => Array(
            [id] => 36
            [name] => Merch
        )
        [Child] => Array(
            [0] => Array(
                [id] => 49
                [name] => Poster
            )
            [1] => Array(
                [id] => 48
                [name] => Sticker
            )
            [2] => Array(
                [id] => 40
                [name] => Apparel
            )
        )
    )
    

    Set 上课也是可以接受的。

    2 回复  |  直到 17 年前
        1
  •  4
  •   Paolo Bergantino    17 年前

    优雅的定义优雅。我认为有些人会把这变成一场高尔夫比赛,而不是简单地做一些有意义的事情,这一点在以后的代码中对任何人来说都是显而易见的:

    $cats = array();
    foreach($categories as $c) {
        $cats[$c['Category']['id']] = $c['Category']['name'];
    }
    

    我怀疑这就是你所拥有的,在这种情况下,我建议你拍拍自己的后背,继续前进。

        2
  •  1
  •   Peter Bailey    17 年前

    preg_match_all( "/\"name\";s:\d+:\"(.*?)\"/i", serialize( $arr ), $matches );
    
    print_r( $matches[1] );
    

    老实说,递归迭代是清晰的最佳选择,即使它不是非常有效或简洁。

    $arr = array(
        "0" => array(
            "Category" => array(
                "id" => 49
                ,"name" => Poster
            )
            ,"Child" => array()
        )
        ,"1" => array(
            "Category" => array(
                "id" => 48
                ,"name" => Sticker
            )
            ,"Child" => array()
        )
        ,"2" => array(
            "Category" => array(
                "id" => 46
                ,"name" => Hat
            )
            ,"Child" => array()
        )
        ,"3" => array(
            "Category" => array(
                "id" => 45
                ,"name" => Hoodie
            )
            ,"Child" => array(
                "0" => array(
                    "id" => 49
                    ,"name" => Poster
                )
                ,"1" => array(
                    "id" => 48
                    ,"name" => Sticker
                )
                ,"2" => array(
                    "id" => 40
                    ,"name" => Apparel
                )
            )
        )
    );
    
    findNames( $arr, $names );
    echo '<pre>';
    print_r( $names );
    echo '</pre>';
    
    function findNames( $source, &$out )
    {
        foreach ( $source as $value )
        {
            if ( isset( $value['name'] ) )
            {
                //  Assumes that if $value['name'] exists, $value['id'] must also exist
                $out[$value['id']] = $value['name'];
                continue;
            }
            if ( is_array( $value ) )
            {
                findNames( $value, &$out );
            }
        }
    }