2016-07-04 5 views
2

私は、可変長のキー名の配列を持っていると私はの追加/編集値は

は、例えば、私が持っている配列に値を代入するために、これらの名前を使用したいです違うの車やバイクの数をリストする配列:inputtin後

$keys1 = ['cars', 'honda', 'jazz']; 
$value1 = 3; 
$keys2 = ['bikes', 'scott']; 
$value2 = 1; 
$keys3 = ['motorbikes', 'harley-davidson', 'dyna', 'street-bob']; 
$value3 = 2; 

$vehicles = [ 
    'cars' => Array 
    (
     'suzuki' => Array 
     (
      'wagon' => 4, 
      'baleno' => 2 
     ), 
     'honda' => Array 
     (
      'civic' => 6 
     ) 
    ), 
    'bikes' => array 
    (
     'raleigh' => 3, 
     'scott' => 3 
    ) 
]; 

私はまた、メインアレイに配置する値とともにキー名の複数のアレイを持っていますG配列は次のようになります。これらすべての値:

$vehicles = [ 
    'cars' => Array 
    (
     'suzuki' => Array 
     (
      'wagon' => 4, 
      'baleno' => 2 
     ), 
     'honda' => Array 
     (
      'civic' => 6, 
      'jazz' => 3 
     ) 
    ), 
    'bikes' => array 
    (
     'raleigh' => 3, 
     'scott' => 1 
    ), 
    'motorbikes' => Array 
    (
     'harley-davidson' => Array 
     (
      'dyna' => Array 
      (
       'street-bob' => 2 
      ) 
     ) 
    ) 
]; 

だから最初の配列は1つが以前に存在しなかった$key => $valueペアを追加します。 2番目のキーは$array2の末尾にあるキーの値を置き換え、最後のキーがなければ新しい配列を作成します。

どのようにして配列をこのように配置できますか?

eval()はすべて私の問題を解決しますが、配列はhtmlから作成されるため、セキュリティ上のリスクは非常に高くなります。キー/値のペアのリストを構築する

答えて

1

あなたの$vehiclesと同じ形式で$keys配列を変換して、再帰的にそれらを置き換えることができます:

$vehicles = [ 
    'cars' => [ 
     'suzuki' => [ 
      'wagon' => 1, 
      'boleno' => 2 
     ] 
    ], 

    'bikes' => [ 
     'scott' => 3 
    ] 

]; 

$keys = ['cars', 'honda', 'jazz']; 
$value = 3; 

function addValues($vehicles, $keys, $value) 
{ 
    $formatted = formatArray($keys, $value); 

    return array_replace_recursive($vehicles, $formatted); 
} 

function formatArray($array, $value) 
{ 
    $format = function ($carry, $item) { 
     return [$item => $carry]; 
    }; 

    return array_reduce(array_reverse($array), $format, $value); 
} 

$vehicles = addValues($vehicles, $keys, $value); 
var_dump($vehicles); 

出力:

array (size=2) 
    'cars' => 
    array (size=2) 
     'suzuki' => 
     array (size=2) 
      'wagon' => int 1 
      'boleno' => int 2 
     'honda' => 
     array (size=1) 
      'jazz' => int 3 
    'bikes' => 
    array (size=1) 
     'scott' => int 3 
+0

これは素晴らしいです。ありがとうございました。 なぜarray_mergeがそこにあるのかわからなかったので、私はそれをテストせずに同じことをしましたが、5倍遅くなりました。それがなぜあるのか教えていただけますか? –

+0

@ChrisStarlingようこそ、私は喜んで助けてくれる。あなたは本当にそこにそれを必要としません。それは実際にはそれなしではもっと速いです。私は以前に2番目の配列でテストしていたので、残りの部分だけです。私は答えを更新します。 – postrel

1

(私の意見で)便利な方法は、以下のようになります:

foreach ($key_paths as $kPath) { 
    $current = null; 
    foreach (array_slice($kPath['key_path'], 0, -1) as $key) { 
     if (is_null($current)) { 
      if (!isset($vehicles[$key])) $vehicles[$key] = []; 
      $current = &$vehicles[$key]; 
     } else { 
      if (!isset($current[$key])) $current[$key] = []; 
      $current = &$current[$key]; 
     } 
    } 
    $current[end($kPath['key_path'])] = $kPath['value']; 
    unset($current); // unsetting reference 
} 

print_r($vehicles); 

// $vehicles is your initial array 

$key_paths = [ 
    ['key_path' => ['cars', 'honda', 'jazz'], 'value' => 3], 
    ['key_path' => ['bikes', 'scott'], 'value' => 1], 
    ['key_path' => ['motorbikes', 'harley-davidson', 'dyna', 'street-bob'], 'value' => 2], 
]; 

そしてここでは、解決策はarray_slice機能と参照を使用しています

出力:

Array 
(
    [cars] => Array 
     (
      [suzuki] => Array 
       (
        [wagon] => 4 
        [baleno] => 2 
       ) 

      [honda] => Array 
       (
        [civic] => 6 
        [jazz] => 3 
       ) 
     ) 

    [bikes] => Array 
     (
      [raleigh] => 3 
      [scott] => 1 
     ) 

    [motorbikes] => Array 
     (
      [harley-davidson] => Array 
       (
        [dyna] => Array 
         (
          [street-bob] => 2 
         ) 
       ) 
     ) 
) 
+0

完璧です、ありがとうございました。 フォローアップの質問 unset($ current)で参照を削除するだけで、配列の特定のキーを解除する方法はありますか? –

+0

配列の特定のキーを直接*設定解除することができます(例えば 'unset($ vehicles ['cars'] ['honda'])')、または配列を反復することによって(例えば 'foreach($ vehicles ($ k == '自転車')unset($ vehicles [$ k]);} ') – RomanPerekhrest

関連する問題