【问题标题】:Create seperate sub array based on array key根据数组键创建单独的子数组
【发布时间】:2015-07-22 12:35:55
【问题描述】:

我需要根据 > 在数组键中出现的次数将单个数组分成子数组,以便我知道谁是父类别,谁不是。请注意,可能的嵌套父项的数量没有限制。

另外,如果存在同名的孩子,如果它有不同的父母,则认为它是唯一的。

我的源数组结构如下所示:

array (
  'Test Parent 2>Test Child>Test Sub Child' => 
  array (
    'content_id_4' => NULL,
  ),
  'Test Parent 3' => 
  array (
    'content_id_4' => NULL,
    'content_id_5' => NULL,
  ),
  'Test Parent>Test Child>Test Sub Child' => 
  array (
    'content_id_3' => NULL,
  ),
  'Test Parent 2 with No Kids' => 
  array (
    'content_id_3' => NULL,
  ),
  'Collections>Sports' => 
  array (
    'content_id_2' => NULL,
    'content_id_22' => NULL,
  ),
  'Collections' => 
  array (
    'content_id_2' => NULL,
    'content_id_22' => NULL,
    'content_id_6' => NULL,
  ),
  'Collections>Charity' => 
  array (
    'content_id_6' => NULL,
  ),
)

在上面的示例中,Test Parent>Test Child>Test Sub Child 表示父类别 Test Parent 有一个子类别 Test ChildTest Child 也是父母,并且有一个名为 Test Sub Child 的孩子,但没有任何孩子。

需要示例输出:

array (
  'Collections' => 
  array (
    'Sports' => NULL,
    'Charity' => NULL,
  ),
  'Test Parent' => 
  array (
    'Test Child' => 
    array (
      'Test Sub Child' => NULL,
    ),
  ),
  'Test Parent 2 with No kids' => NULL,
  'Study' => 
  array (
    'Study Groups' => NULL,
  ),
)

我尝试了一个解决方案,但无法获得正确的语法,以便我可以创建一个包含孩子的孩子的额外数组。

我不一定需要重构我的示例。我只是在寻找最有效的解决方案。

我的示例代码

$category_structure = array();
foreach($event_categories as $main_cat => $content_ids) {

    $this_category_list = explode('>', $main_cat);

    $this_cat = array();
    $this_parent = array_shift($this_category_list);


    foreach($this_category_list as $cat) {
        $this_cat[$this_parent][$cat] = null;
    }

    $category_structure = array_merge_recursive($this_cat, $category_structure);


}

【问题讨论】:

  • 与其发布数组的var_dump(),不如考虑发布数组的var_export()
  • @nickb - 注意到并修复
  • 你能显示代码吗,这个数组是从哪里来的?必须有一些东西可以使这变得容易。 @DaveO'Dwyer
  • @Viral 源数组来自 CMS - 我无法控制它的数据结构。

标签: php arrays key


【解决方案1】:

这应该对您有用,确保结果中没有零索引项。我认为来自array_merge_recursive,通过将空值项目合并到具有关联键的项目。

虽然它不像 P0rnflake 的 解决方案那样优雅,但我相信你会明白的。

$collect = array();
$result = array();
$last = "";
foreach($event_categories as $main_cat => $content_ids) {
    if (strpos($last, $main_cat) === false) {
        array_push($collect, explode('>', $main_cat));
    }
    $last = $main_cat;
} 
array_walk($collect, function($value) use (&$result) {
    $out = array();
    $cur = &$out;
    foreach ($value as $array) {
        if (count($value) !== 1) {
            $cur[$array] = array();
        } else {
            $cur[$array] = null;    
        }
        $cur = &$cur[$array];
    }
    $cur = null;
    $result = array_merge_recursive($result, $out);
});
var_dump($result);

【讨论】:

  • 谢谢戴夫。非常感谢。这完全符合预期。
  • 当然,愉快的编码! ;-)
【解决方案2】:

此解决方案应该适用于 php >= 5.3.0($yourArray 是输入数组):

// anonymous recursive function which merges a flat numeric array 
// into a hierarchy, f.e. array('parent','child','grandchild')
// will be built to a hierarchical array
$treeBuilder = function($numArray) use (&$treeBuilder) {
    if(isset($numArray[1])) {
        //recursive merge needed, there are still entries left
        return array(
            $numArray[0] => $treeBuilder(array_slice($numArray, 1))
        );
    }
    //end is reached
    return array(
        $numArray[0] => null
    );
};

$result = array();
foreach (array_keys($yourArray) as $key) {
    // loop through exploded keys and merge results
    $hierarchy = explode('>', $key);
    $result = array_merge_recursive($result, $treeBuilder($hierarchy));
}
var_dump($result);

【讨论】:

  • 感谢您的尝试。生成的数组结构看起来与所有返回数组中都存在的值为 null 的键 0 完全吻合。它似乎来自代码return array( $numArray[0] => null
  • 是的,你是对的,我认为这发生在没有分隔符的“收藏”条目中
猜你喜欢
  • 1970-01-01
  • 2021-09-29
  • 2020-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多