如何" roll"一个未知深度的PHP数组?

时间:2017-01-26 09:54:18

标签: php recursion

我不确定我想要完成的内容是什么,但如果我有这样的数组结构:

[
  'owner' => 'Fred',
  'cars' => [
    0 =>  [
     'model' => 'Toyota',
     'passengers' => [
         0 => [
          'name' => "Tom",
          'age' => 35,
          'hobbies' => [
            0 => [
              'name' => 'Chess',
              'exp' => 'Master'
            ],
            1 => [
              'name' => 'Soccer',
              'exp' => 'Novice'
            ]
           ]
         ],
         1 => [
          'name' => "Bill", 
          'age' => 30,
          'hobbies' => [
            0 => [
              'name' => 'Basketball',
              'exp' => 'Novice'
            ],
            1 => [
              'name' => 'Football',
              'exp' => 'Expert'
            ]
          ]
        ]
      ]
   ]
 ]

我希望能够基于密钥在模板中进行嵌套替换。因此,对于这个例子,我将有3个模板,#34;汽车","乘客"和爱好"。

cars.txt

Model: <<model>> Passengers: <<passengers>>

passengers.txt

<<name>> (<<age>>), <<hobbies>>;

hobbies.txt

<<hobby>> - <<exp>>,

所以我想&#34; roll&#34;阵列最终只是:

[
  'owner' => 'Fred',
  'cars' => [
     0 => "Model: Toyota, Passengers: Tom (37) Chess - Master, Soccer - Novice; Bill (30) Basketball - Novice, Football - Expert;"
   ]
]

我一直在努力学习如何走到最深的叶子,以便在更换巢穴后从外面卷起来。

我该怎么做?

3 个答案:

答案 0 :(得分:0)

为了构建cars字符串,您需要在每个嵌入式数组上iterate。在下面的示例中,我使用implode来构建passengershobbies数组中的字符串:

<?php

$array = array(
    'owner' => 'Fred',
    'cars' => array(
        0 =>  array(
            'model' => 'Toyota',
            'passengers' => array(
                0 => array(
                    'name' => "Tom",
                    'age' => 35,
                    'hobbies' => array(
                        0 => array(
                            'name' => 'Chess',
                            'exp' => 'Master'
                        ),
                        1 => array(
                            'name' => 'Soccer',
                            'exp' => 'Novice'
                        )
                    )
                ),
                1 => array(
                    'name' => "Bill", 
                    'age' => 30,
                    'hobbies' => array(
                        0 => array(
                            'name' => 'Basketball',
                            'exp' => 'Novice'
                        ),
                        1 => array(
                            'name' => 'Football',
                            'exp' => 'Expert'
                        )
                    )
                )
            )
        )
    )
);

$output = array('owner' => '', 'cars' => array());
$output['owner'] = $array['owner'];
foreach ($array['cars'] as $car) {
    $output_car = '';
    $output_passengers = array();
    foreach ($car['passengers'] as $passenger) {
        $output_hobbies = array();
        foreach ($passenger['hobbies'] as $hobby) {
            $output_hobbies[] = $hobby['name'] . ' - ' . $hobby['exp'];
        }
        $output_passengers[] = $passenger['name'] . ' (' . $passenger['age'] . ') ' . implode(', ', $output_hobbies);
    }
    $output_car = 'Model: ' . $car['model'] . ', Passengers: ' . implode('; ', $output_passengers);
    $output['cars'][] = $output_car;
}

var_dump($output);

将输出:

array (size=2)
  'owner' => string 'Fred' (length=4)
  'cars' => 
    array (size=1)
      0 => string 'Model: Toyota, Passengers: Tom (35) Chess - Master, Soccer - Novice; Bill (30) Basketball - Novice, Football - Expert' (length=117)

我对array functions并不熟悉,但我敢打赌解决方案对他们来说可能更简单(或至少更轻)。

答案 1 :(得分:0)

试试这个:

$data = [
    ['owner' => 'Fred',
        'cars' => [
            0 => [
                'model' => 'Toyota',
                'passengers' => [
                    0 => [
                        'name' => "Tom",
                        'age' => 35,
                        'hobbies' => [
                            0 => [
                                'name' => 'Chess',
                                'exp' => 'Master'
                            ],
                            1 => [
                                'name' => 'Soccer',
                                'exp' => 'Novice'
                            ]
                        ]
                    ],
                    1 => [
                        'name' => "Bill",
                        'age' => 30,
                        'hobbies' => [
                            0 => [
                                'name' => 'Basketball',
                                'exp' => 'Novice'
                            ],
                            1 => [
                                'name' => 'Football',
                                'exp' => 'Expert'
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
];

$result = [];

foreach ($data as $d) {
    $record['owner'] = $d['owner'];
    foreach($d['cars'] as $car){
        $car_data = "Model: ".$car['model'].", Passengers: ";
        $passengers = '';
        foreach($car['passengers'] as $p){
            $passenger = $p['name']."(".$p['age'].") ";
            $i = 0;
            $len = count($p['hobbies']);
            $hobbies = '';
            foreach($p['hobbies'] as $h){
                $hobby = '';
                if ($i < $len - 1) {
                    $hobby = $h['name']." - ".$h['exp'].",";
                } else if ($i == $len - 1) {
                    $hobby = $h['name']." - ".$h['exp'];
                }
                $i++;
                $hobbies = $hobbies.$hobby." ";
            }
            $passenger = $passenger.$hobbies.";";
            $passengers = $passengers.$passenger." ";
        }
        $car_data = $car_data.$passengers;
    }
    $record['cars'][] = $car_data;
    $result[] = $record;
}

print_r($result);

的输出
  

数组([0] =&gt;数组([所有者] =&gt; Fred [cars] =&gt;数组([0] =&gt;模型:   丰田,乘客:汤姆(35)国际象棋 - 大师,足球 - 新手;法案(30)   篮球 - 新手,足球 - 专家; )))

答案 2 :(得分:0)

我终于明白了:

function normalizeTemplateVars($vars,$templates) {
  $expand_vars = function($parent_key,$parent_value) use($vars,$templates,&$expand_vars) {
    if(!is_array($parent_value)) return $parent_value;

    $tmp = [];
    foreach($parent_value as $item_index => $item_value) {
      foreach($item_value as $k => $v) $parent_value[$item_index][$k] = $expand_vars($k,$v);

      //mergeAndPurge just replaces variables in template
      $tmp[] = mergeAndPurge($parent_value[$item_index],$templates[$parent_key]);
    }

    return implode($tmp,PHP_EOL);      
  };

  $ret = [];
  foreach($vars as $k => $v) $ret[$k] = $expand_vars($k,$v);

  return $ret;
}

$replacement_vars = normalizeTemplateVars($vars, ['cars' => '<<owner>> <<cars>>','passengers' => '<<name>> (<<age), <<hobbies>>', 'hobbies' => '<<name>> - <<exp>>']);

这将返回一个只有“汽车”和“所有者”的1级深度数组,这正是我正在寻找的。