2014-09-13 89 views
0

我正在寻找一个干净的解决方案来转换嵌套数组。遍历嵌套数组并转换一些值

这里就是我想实现...

原始数组:

$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', 
    ), 
    ) 
); 

基本上,我需要遍历数组,发现所有带有“班级”钥匙的孩子,并将其转换成同名的对象。

回答

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); 

结果:

(注意,第一个阵列变成一个对象,因为它包含字段“类”嫌我猜你可以轻松调整功能,如果你不想要那样的行为)

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 
       ) 

     ) 

) 
+0

谢谢,这就是我一直在寻找的。 – 2014-09-16 08:40:12

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. 每个类的所有相关属性都是公共的,并且可以从课外设置。