遍历嵌套数组并转换一些值

时间:2014-09-13 18:54:41

标签: php arrays multidimensional-array

我正在寻找一种干净的解决方案来转换嵌套数组。

这是我想要实现的目标......

原始阵列:

  $map = array(
    'name' => 'super test',
    'machine_name' => 'super_test',
    'class' => 'openlayers_map_map',
    'options' => array(
      'width' => 'auto',
      'height' => '300px',
      'contextualLinks' => 1,
      'provideBlock' => 1,
      'view' => array(
        'center' => array(
          'lat' => '0',
          'lon' => '0',
        ),
        'rotation' => '0',
        'zoom' => '2',
      ),
      'layers' => array(
        '0' => array(
          'name' => 'Ma super layer',
          'machine_name' => 'plouf',
          'class' => 'openlayers_layer_tile',
          'options' => array(
            'source' => array(
              'name' => 'Ma super layer',
              'machine_name' => 'plouf',
              'class' => 'openlayers_source_osm'
            ),
            'param1' => 'ca roule'
          )
        ),
      ),
      'controls' => array(
        'control_mouseposition',
        '0' => array(
          'name' => 'Control attribution',
          'machine_name' => 'openlayers_control_attribution',
          'class' => 'openlayers_control_attribution',
          'options' => array(
            'collapsible' => 1
          )
        ),
        'control_rotate',
        'control_zoom',
      ),
      'interactions' => array(
        'interaction_doubleclickzoom',
        'interaction_dragpan',
        'interaction_dragrotateandzoom',
        'interaction_mousewheelzoom',
      ),
    )
  );

最终阵列:

  $map = array(
    'name' => 'super test',
    'machine_name' => 'super_test',
    'class' => 'openlayers_map_map',
    'options' => array(
      'width' => 'auto',
      'height' => '300px',
      'contextualLinks' => 1,
      'provideBlock' => 1,
      'view' => array(
        'center' => array(
          'lat' => '0',
          'lon' => '0',
        ),
        'rotation' => '0',
        'zoom' => '2',
      ),
      'layers' => array(
        '0' => (object) openlayers_layer_tile
          'name' => 'Ma super layer',
          'machine_name' => 'plouf',
          'class' => 'openlayers_layer_tile',
          'options' => array(
            'source' => (object) openlayers_source_osm
              'name' => 'Ma super layer',
              'machine_name' => 'plouf',
              'class' => 'openlayers_source_osm'
            ),
            'param1' => 'ca roule'
          )
        ),
      ),
      'controls' => array(
        'control_mouseposition',
        '0' => (object) openlayers_control_attribution
          'name' => 'Control attribution',
          'machine_name' => 'openlayers_control_attribution',
          'class' => 'openlayers_control_attribution',
          'options' => array(
            'collapsible' => 1
          )
        ),
        'control_rotate',
        'control_zoom',
      ),
      'interactions' => array(
        'interaction_doubleclickzoom',
        'interaction_dragpan',
        'interaction_dragrotateandzoom',
        'interaction_mousewheelzoom',
      ),
    )
  );

基本上,我需要遍历阵列,找到所有孩子的班级'键并将它们转换为同名的对象。

2 个答案:

答案 0 :(得分:1)

如果您没有准备好实例化类,则此代码将创建匿名对象。 (类名仍作为属性出现。)

function class_to_object (&$arr) {

  if (is_array($arr)) {
    foreach ($arr as $key => &$val) {
      class_to_object($val);
    }

    if (isset($arr['class'])) {
      $arr = (object) $arr;
    }
  }

}

class_to_object($map);

结果:

(注意第一个数组变成了一个对象,因为它也包含字段“class”。如果你不想要那个行为,我想你可以很容易地调整函数)

stdClass Object
(
    [name] => super test
    [machine_name] => super_test
    [class] => openlayers_map_map
    [options] => Array
        (
            [width] => auto
            [height] => 300px
            [contextualLinks] => 1
            [provideBlock] => 1
            [view] => Array
                (
                    [center] => Array
                        (
                            [lat] => 0
                            [lon] => 0
                        )

                    [rotation] => 0
                    [zoom] => 2
                )

            [layers] => Array
                (
                    [0] => stdClass Object
                        (
                            [name] => Ma super layer
                            [machine_name] => plouf
                            [class] => openlayers_layer_tile
                            [options] => Array
                                (
                                    [source] => stdClass Object
                                        (
                                            [name] => Ma super layer
                                            [machine_name] => plouf
                                            [class] => openlayers_source_osm
                                        )

                                    [param1] => ca roule
                                )

                        )

                )

            [controls] => Array
                (
                    [0] => stdClass Object
                        (
                            [name] => Control attribution
                            [machine_name] => openlayers_control_attribution
                            [class] => openlayers_control_attribution
                            [options] => Array
                                (
                                    [collapsible] => 1
                                )

                        )

                    [1] => control_rotate
                    [2] => control_zoom
                )

            [interactions] => Array
                (
                    [0] => interaction_doubleclickzoom
                    [1] => interaction_dragpan
                    [2] => interaction_dragrotateandzoom
                    [3] => interaction_mousewheelzoom
                )

        )

)

答案 1 :(得分:0)

这个完全未经测试的递归函数可能会让您走上正轨:

function recursive_hydrate_array($arr)
{
  if(!is_array($arr) || !isset($arr["class"]))
  {
    throw new Exception("Argument is not an array or does not have a 'class' key.");
  }

  $klass = $arr["class"];
  unset($arr["class"]);

  $obj = new $klass();

  foreach($arr as $k => $v)
  {
    if(is_array($arr[$k]) && isset($arr[$k]["class"]))
    {
      $obj->{$k} = recursive_hydrate_array($arr[$k]);
    }
    else
    {
      $obj->{$k} = $arr[$k];
    }
  }

  return $obj;
}

请注意,我在这里做了三个假设:

  1. 有问题的课程已经存在。
  2. 可以在不将任何参数传递给构造函数的情况下实例化每个类。
  3. 每个班级的所有相关属性都是公开的,可以在课堂外设置。