【问题标题】:adding one more level to a hierarchical multi-dimensional array向分层多维数组再添加一层
【发布时间】:2015-01-18 20:51:19
【问题描述】:

更新:

这是一个从 mysql 获取的平面数组。我使用闭包表来存储层次关系:

Array
(
    [0] => Array
        (
            [brand] => Intel
            [id] => 53
            [name] => CPU 1978
            [parent_id] => 0
        )

    [1] => Array
        (
             [brand] => Asus
             [id] => 537
             [name] => CPU 1999
             [parent_id] => 53
        )

    [2] => Array
        (
             [brand] => HTC
             [id] => 538
             [name] => CPU 1998
             [parent_id] => 53
        )
)

我有一些数据显示新产品基于哪些古老产品。我正在使用以下代码将平面数组转换为分层的多维数组:

function buildTree(array $elements, $parentId = 0) {
 $branch = array();

 foreach ($elements as $element) {
    if ($element['parent_id'] == $parentId) {
        $children = buildTree($elements, $element['id']);
        if ($children) {
            $element['children'] = $children;
        }
        $branch[] = $element;
    }
 }

 return $branch;
}

结果:

Array
(
    [0] => Array
        (
            [brand] => Intel
            [id] => 53
            [name] => CPU 1978
            [parent_id] => 0
            [children] => Array
                (
                    [0] => Array
                        (
                            [brand] => Asus
                            [id] => 537
                            [name] => CPU 1999
                            [parent_id] => 53
                        )

                    [1] => Array
                        (
                            [brand] => HTC
                            [id] => 538
                            [name] => CPU 1998
                            [parent_id] => 53
                        )

                )

        )

)

我想通过在第一级添加一个新键 brands 来重组树,并将儿童品牌提取为第二级的数组键,如下所示:

Array
(
    [0] => Array
        (
            [brand] => Intel
            [id] => 53
            [name] => CPU 1978
            [parent_id] => 0
            [brands]=> Array
                    (
                      [Asus]=> Array
                           (
                             [0] => Array
                             (
                               [id] => 537
                               [name] => CPU 1999
                               [parent_id] => 53
                             )
                           )

                      [HTC] => Array
                          (
                            [0]=>Array
                              (
                                [id] => 538
                                [name] => CPU 1998
                                [parent_id] => 53
                              )
                          )
                      [Intel]=>Array() // Keep this one for new CPU from Intel
                    )


        )

)

我已经尝试创建一个更多的功能,将品牌插入父级,但我的问题是,我怎样才能将孩子的 CPU 放入相应的品牌中?

function brand(array $elements,$children){
  $branch = array();
  foreach($elements as $k=>$element){          
    /* if($element['brand'] == $children['brand']) not working **/
     $branch[$element['brand']] = $children;
  }
  return $branch;
}

function buildTree(array $elements, $parentId = 0) {
 $branch = array();

 foreach ($elements as $element) {
    if ($element['parent_id'] == $parentId) {
        $children = buildTree($elements, $element['id']);
        if ($children) {
            $element['brands'] = brand($elements,$children);

        }
        $branch[] = $element;
    }
 }

 return $branch;
}

这给了我这个结果:

 Array
    (
        [0] => Array
            (
                [brand] => Intel
                [id] => 53
                [name] => CPU 1978
                [parent_id] => 0
                [brands]=> Array
                        (
                          [Asus]=> Array
                               (
                                 [0] => Array
                                 (
                                   [brand]=> Asus
                                   [id] => 537
                                   [name] => CPU 1999
                                   [parent_id] => 53
                                 )
                                 [1]=>Array
                                  (
                                    [brand]=>HTC
                                    [id] => 538
                                    [name] => CPU 1998
                                    [parent_id] => 53
                                  )
                               )

                          [HTC] => Array
                              (
                                 [0] => Array
                                 (
                                   [brand]=> Asus
                                   [id] => 537
                                   [name] => CPU 1999
                                   [parent_id] => 53
                                 )
                                  [1]=>Array
                                  (
                                    [brand]=>HTC
                                    [id] => 538
                                    [name] => CPU 1998
                                    [parent_id] => 53
                                  )
                              )
                          [Intel]=>Array(
                              (
                                 [0] => Array
                                 (
                                   [brand]=> Asus
                                   [id] => 537
                                   [name] => CPU 1999
                                   [parent_id] => 53
                                 )
                                  [1]=>Array
                                  (
                                    [brand]=>HTC
                                    [id] => 538
                                    [name] => CPU 1998
                                    [parent_id] => 53
                                  )
                              )
                           )
                      )


            )

    )

【问题讨论】:

  • 您能否分享您用于进一步处理的第一个数组。这将有助于为您的问题提供正确的答案。
  • @anantkumarsingh 查看我的帖子。我已经用从 mysql 获取的数组更新了它,用于构建层次数组。

标签: php arrays tree hierarchical-data


【解决方案1】:

RedGiant,以下函数将获取您现有 buildTree() 方法的输出并递归转换它,使数组树中的所有 children 元素都将替换为 brands

function brand(array $elements)
{
    // Return early if parent has no children
    if (! array_key_exists('children', $elements)) {
        return $elements;
    }

    // Initialise local values
    $brands = array();

    // Transform children (recursively)
    foreach ((array) $elements['children'] as $child) {
        $brand = $child['brand'];
        unset($child['brand']);

        // Use call_user_func() and __function__ to prevent name dependency
        // within the function itself. If required, this can be replaced with:
        // $brands[$brand] = array(brand($child);
        $brands[$brand] = array(call_user_func(__function__, $child));
    }

    // Replace children with brands
    unset($elements['children']);
    $elements['brands'] = $brands;

    return $elements;
}

函数应该通过array_map()调用,即:

$old_tree = buildTree($original_flat_array)
$new_tree = array_map('brand', buildTree($original_flat_array));

此解决方案的优点是它保留了所有现有的数组键(显然,children 除外)。因此,您将来可能添加到原始平面数组中的任何键都将被传递到新的转换后的数组树中,而无需修改代码。

【讨论】:

    【解决方案2】:

    编辑:当一个品牌有多个子元素时,我之前的回答非常失败。下面是一个更强大的解决方案。

    function buildTree(array $elements, $parentId = 0)
    {
        $branch = [];
    
        foreach ($elements as $element) {
            if ($element['parent_id'] == $parentId) {
                $element['brands'] = brand(buildTree($elements, $element['id']));
    
                $branch[] = $element;
            }
        }
    
        return $branch;
    }
    
    function brand(array $elements)
    {
        $branch = [];
        foreach ($elements as $element) {
            $branch[$element['brand']][] = [
                'id' => $element['id'],
                'name' => $element['name'],
                'parent_id' => $element['parent_id'],
            ];
        }
    
        return $branch;
    }
    

    这会从原始数组返回以下内容:

    Array
    (
        [0] => Array
            (
                [brand] => Intel
                [id] => 53
                [name] => CPU 1978
                [parent_id] => 0
                [brands] => Array
                    (
                        [Asus] => Array
                            (
                                [0] => Array
                                    (
                                        [id] => 537
                                        [name] => CPU 1999
                                        [parent_id] => 53
                                    )
                            )
                        [HTC] => Array
                            (
                                [0] => Array
                                    (
                                        [id] => 538
                                        [name] => CPU 1998
                                        [parent_id] => 53
                                    )
                            )
                    )
            )
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-08
      • 2012-05-17
      • 1970-01-01
      相关资源
      最近更新 更多