2017-01-26 3 views
-1

私は私が達成しようとしている何のための適切な用語が何であるかわからないんだけど、私はこのような配列構造がある場合:未知の深さのPHP配列を "ロールアップ"するには?

[ 
    '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つのテンプレート、「車」、「乗客」、「趣味」を持っています。

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

は、だから私は最終的にはちょうどされて入っまでの "ロール" 配列をしたい

cars.txt

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

passengers.txt

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

hobbies.txt:

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

私はちょうど最も深い葉に歩いていくことに苦労しています。

どうすればいいですか?

+0

[配列関数](http://php.net/manual/en/ref.array.php)のいずれかを使用して配列を反復処理します。 –

+0

'編集: 私は最後にそれを理解しました:' - あなたの質問を編集する代わりに。これを通常の回答として投稿し、問題を閉じるためにそれを受け入れてください! –

答えて

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レベルの深さの配列を返します。

0

cars文字列を作成するには、埋め込み配列ごとにiterateが必要です。下の例では、私はpassengershobbies配列から文字列を構築するためにimplodeを使用:

<?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とその慣れていないんだけど、私は解決策を賭けますそれらとより簡単に(または少なくとも軽く)することができます。

+0

返事をありがとう。私は一般的なアプローチのより多くを探しています。私は、各アイテムに対してレンダリングされる必要があるキーに対応する名前のテンプレートセットを持っています。私は木の終わりまで歩く良い方法を見つけることを望んでいました。そして、後で親に戻って代わりに使うことができるように、それぞれの鍵をレンダリングしてレンダリングします。あなたが最初の乗客のための趣味で行ったとき だから好きな、あなたのような配列が残されると思い: 「趣味」=>「//レンダリング文字列」今 私は<を使用することができると思います>乗客のテンプレートでは、最大乗客w /乗客cars.txt。 – user126715

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] =>アレイ([所有者] =>フレッド[車] =>配列([0 ] =>モデル: トヨタ、乗客:トム(35)チェス - マスター、サッカー - 初心者;ビル(30) バスケットボール - 初心者、フットボール - エキスパート;)))

+1

'cars'要素文字列の末尾に'; 'が続きます(https://eval.in/724695)。配列を構築し、文字列を構築する代わりに 'implode'を使うことを考慮する必要があります。 – roberto06

+0

返信いただきありがとうございます。私はより一般化されたアプローチを望んでいた。実際の使用例では、置換配列のキーに対応する一連のテンプレートがあります。特定のエントリがcarの場合、各アイテムをcars.txtテンプレートに対してレンダリングし、それを返します。車は<>に置き換えられます...乗客は、<>に置き換えます。だから私は最初にそれをレンダリングすることによって "趣味"を文字列に変える必要があります...そして、私は乗客をレンダリングすることができます...乗客はcars.txtで使用することができます – user126715

関連する問題