在PHP中将1D数组转换为多维数组

时间:2009-07-09 15:33:45

标签: php arrays

我有这个数组:

Array
(
    [1] => animal
    [1-1] => turtle
    [1-1-1] => sea turtle
    [1-1-2] => box turtle
    [1-1-3] => green turtle
    [1-1-3-1] => green turtle with brown tail
)

我想要一些如何将其转换为:

Array
(
    [1-title] => animal
    [1-sons] => array(
            [1-1-title] => turtle
            [1-1-sons] => array(
                    [1-1-1] => sea turtle
                        [1-1-2] => box turtle
                    [1-1-3-title] => green turtle
                    [1-1-3-sons] => array(
                            [1-1-3-title] => green turtle
                                  )
                    )
              )
)

或者你可以建议一个更好的方法来组织输出的数组..

但该怎么做?

我知道这根本不是一件容易的事,我正在编写一个解析器来处理数据并从中创建树。

提前感谢您的帮助和建议..

5 个答案:

答案 0 :(得分:8)

组织数据的最简单方法是这样:

array (
  'Animal' =>
  array (
    'Turtle' =>
    array (
      'Sea Turtle',
      'Box Turtle',
      'Green Turtle' =>
      array (
        'Green Turtle With Brown Tail',
      ),
      'Common Turtle',
    ),
  ),
);

// Or, otherwise written (equivalent to the above)

$animals = array();
$animals['Animal'] = array();
$animals['Animal']['Turtle'] = array();
$animals['Animal']['Turtle'][] = 'Sea Turtle';
$animals['Animal']['Turtle'][] = 'Box Turtle';
$animals['Animal']['Turtle']['Green Turtle'] = array();
$animals['Animal']['Turtle']['Green Turtle'][] = 'Green Turtle With Brown Tail';
$animals['Animal']['Turtle'][] = 'Common Turtle';

基本上,动物的名称是值,除非它有子项,那么值是一个数组,键是动物名称。


这样,您可以通过执行以下操作轻松解析值:

parse_animals($animals);

function parse_animals($array, $indent = 0) {
  if(!is_array($array)) return;    // A little safe guard in case.

  foreach($array as $key => $value) {
    echo str_repeat('  ', $indent) . "- ";

    if(is_array($value)) {
      echo $key . "\n";
      parse_animals($value, $indent + 1);
    } else {
      echo $value . "\n";
    }
  }
}

控制台中的上述内容将输出以下内容:

- Animal
  - Turtle
    - Sea Turtle
    - Box Turtle
    - Green Turtle
      - Green Turtle With Brown Tail
    - Common Turtle

编辑:这是一个将其输出到网页的版本。

function parse_animals_web($array) {
  if(!is_array($array)) return;    // A little safe guard in case.

  foreach($array as $key => $value) {
    echo '<ul>';

    if(is_array($value)) {
      echo '<li>' . htmlentities($key) . "</li>";
      parse_animals_web($value);
    } else {
      echo '<li>' . htmlentities($value) . "</li>";
    }

    echo '</ul>';
  }
}

输出结果为:

  
      
  • 动物      
        
    •   
    • 海龟
    •   
    • Box Turtle
    •   
    • 绿海龟      
          
      • 绿尾龟与棕色尾巴
      •   
    •   
    • Common Turtle
    •   
  •   

也许你想要一个动物的孩子。

function get_children_of($array, $name) {
  foreach($array as $key => $value) {
    if(is_array($value)) {
      if($key === $name) {
        return $value;
      } else {
        return get_children_of($value, $name);
      }
    }
  }

  return array();
}

现在我们可以获得Green Turtle的所有孩子并输出它们。

$green_turtle = get_children_of($animals, 'Green Turtle');
parse_array($green_turtle);

输出结果为:

- Green Turtle With Brown Tail

编辑:既然你说你的输入数据是那种奇怪的格式,那么这个函数会把你的数组转换成我上面指定的格式:

function convert_array($array) {
  $new_array = array();

  $keys = array_keys($array);
  foreach($keys as $key) {
    $level = explode('-', $key);
    $cur_level = &$new_array;
    $cur_key = '';

    foreach($level as $o_key) {
      $cur_key = ltrim($cur_key . '-' . $o_key, '-');
      $next_key = $cur_key . '-1';
      $value = $array[$cur_key];
      $has_child = array_key_exists($next_key, $array);

      if($has_child) {
        if(!array_key_exists($value, $cur_level)) {
          $cur_level[$value] = array();
        }
        $cur_level = &$cur_level[$value];
      } else {
        $cur_level[] = $value;
      }
    }
  }

  return $new_array;
}

答案 1 :(得分:1)

这实际上取决于您将如何使用生成的树。你能否写出更多关于这方面的细节?

答案 2 :(得分:0)

试试这个:

$array = array(
    '1' => 'animal',
    '1-1' => 'turtle',
    '1-1-1' => 'sea turtle',
    '1-1-2' => 'box turtle',
    '1-1-3' => 'green turtle',
    '1-1-3-1' => 'green turtle with brown tail'
);
$tree = array();
foreach ($array as $path => $val) {
    $segments = explode('-', $path);
    $last = array_pop($segments);
    $tmp = &$tree;
    $path = '';
    foreach ($segments as $segment) {
        $path .= $segment.'-';
        if (!isset($tmp[$path.'sons'])) {
            $tmp[$path.'sons'] = array();
        }
        $tmp = &$tmp[$path.'sons'];
    }
    $tmp[$path.$last.'-title'] = $val;
}
print_r($tree);

但是你的数据结构没有多大意义。

答案 3 :(得分:0)

$result = array();
foreach ($array as $position => $text) {
    $p = explode('-', $position); 
    putIntoTree($result, $p, $text);
}

function putIntoTree( &$tree, $posInfo, $item ) {
    $index = array_shift($posInfo) - 1;

    if (!count($posInfo)) {
        $tree[$index]['name'] = $item;
    } else {         
        if (!isset($tree[$index]['children'])) {
            $tree[$index]['children'] = array();
        }
        putIntoTree($tree[$index]['children'], $posInfo, $item);
    }   
}    

结果,这似乎是一种合理的方式来保存数据。

Array
(
    [0] => Array
        (
            [name] => animal
            [children] => Array
                (
                    [0] => Array
                        (
                            [name] => turtle
                            [children] => Array
                                (
                                    [0] => Array
                                        (
                                            [name] => sea turtle
                                        )

                                    [1] => Array
                                        (
                                            [name] => box turtle
                                        )

                                    [2] => Array
                                        (
                                            [name] => green turtle
                                            [children] => Array
                                                (
                                                    [0] => Array
                                                        (
                                                            [name] => green turtle with brown tail
                                                        )
                                                )
                                        )
                                )
                        )
                )
        )
)

答案 4 :(得分:0)

您要实现的是某种嵌套集,因此实现它的最简单方法是将父ID保存在子条目中:

// the tree
0 => array(parent => NULL, name => turtle),
1 => array(parent => 0, name => green turtle),
2 => array(parent => 0, name => blue turtle),
3 => array(parent => 1, name => green turtle with yellow nose)

您可以使用简单的递归函数遍历此层次结构。

如果你使用对象而不是关联数组,你甚至可以获得一些性能提升。