PHP 作 ▸ 2018-12-15 16:34 テーブル状の2次元配列を、複数のカラム値をキーにした多次元連想配列に変形 #PHP 複合キーのマスタとかをメモリ上にキャッシュしたい時に // これを… $before = [ ['key1' => 'A', 'key2' => 'X', 'key3' => '1', 'name' => '塩'], ['key1' => 'A', 'key2' => 'Y', 'key3' => '1', 'name' => '砂糖'], ['key1' => 'A', 'key2' => 'Y', 'key3' => '2', 'name' => 'しょうゆ'], ['key1' => 'B', 'key2' => 'X', 'key3' => '1', 'name' => 'バルサミコ酢'], ]; // こう $after = [ 'A' => [ 'X' => [ '1' => ['key1' => 'A', 'key2' => 'X', 'key3' => '1', 'name' => '塩'], ], 'Y' => [ '1' => ['key1' => 'A', 'key2' => 'Y', 'key3' => '1', 'name' => '砂糖'], '2' => ['key1' => 'A', 'key2' => 'Y', 'key3' => '2', 'name' => 'しょうゆ'], ], ], 'B' => [ 'X' => [ '1' => ['key1' => 'B', 'key2' => 'X', 'key3' => '1', 'name' => 'バルサミコ酢'], ], ] ]; なお、キーがひとつでよければ1行でできます。 array_combine(array_column($rows, 'キーのカラム名'), $rows));が、複数だと無理です。 なので多次元に対応してる関数作りました。第三引数を true にすると、キー重複時に例外を吐くようになります。true を指定しなかった場合、重複レコードは1行目しか残りません。 array_dict/** * レコードセット状の2次元配列から、指定カラムの値をキーにした多次元連想配列を作成して返却 * @param array $rows レコードセット状の2次元配列 * @param string|array $column_keys キーにするカラム名 (配列で複数指定可) * @param boolean $disallow_duplicate trueならキー重複時に例外 (初期値false) * @return array * @throws RuntimeException $disallow_duplicateがtrueかつキー重複時 */ function array_dict(array $rows, $column_keys, $disallow_duplicate = false) { if (!is_array($column_keys)) { $column_keys = [$column_keys]; } $column_key = array_shift($column_keys); $list = []; foreach ($rows as $row) { if (!isset($list[$row[$column_key]])) { $list[$row[$column_key]] = []; } $list[$row[$column_key]][] = $row; } $dict = []; foreach ($list as $key => $arr) { if (empty($column_keys)) { if ($disallow_duplicate && count($arr) > 1) { throw new RuntimeException("キーが重複している行があります。\n".print_r($arr[0], true)); } $dict[$key] = $arr[0]; } else { $dict[$key] = array_dict($arr, $column_keys, $disallow_duplicate); } } return $dict; }使い方$rows = [ ['key1' => 'A', 'key2' => 'X', 'key3' => '1', 'name' => '塩'], ['key1' => 'A', 'key2' => 'Y', 'key3' => '1', 'name' => '砂糖'], ['key1' => 'A', 'key2' => 'Y', 'key3' => '2', 'name' => 'しょうゆ'], ['key1' => 'B', 'key2' => 'X', 'key3' => '1', 'name' => 'バルサミコ酢'], ]; $dict = array_dict($rows, 'key1'); var_export($dict); /* -> array ( 'A' => array ( 'key1' => 'A', 'key2' => 'X', 'key3' => '1', 'name' => '塩', ), 'B' => array ( 'key1' => 'B', 'key2' => 'X', 'key3' => '1', 'name' => 'バルサミコ酢', ), ) */ $dict = array_dict($rows, ['key1', 'key2', 'key3']); var_export($dict); /* -> array ( 'A' => array ( 'X' => array ( 1 => array ( 'key1' => 'A', 'key2' => 'X', 'key3' => '1', 'name' => '塩', ), ), 'Y' => array ( 1 => array ( 'key1' => 'A', 'key2' => 'Y', 'key3' => '1', 'name' => '砂糖', ), 2 => array ( 'key1' => 'A', 'key2' => 'Y', 'key3' => '2', 'name' => 'しょうゆ', ), ), ), 'B' => array ( 'X' => array ( 1 => array ( 'key1' => 'B', 'key2' => 'X', 'key3' => '1', 'name' => 'バルサミコ酢', ), ), ), ) */