0
0

More than 1 year has passed since last update.

【php】複数の連想配列を一つにまとめる自作関数 バルクインサート等に便利

Last updated at Posted at 2022-09-13

概要

例えば下のような入力フォームがあり、【姓の全リクエスト】【名の全リクエスト】【年齢の全リクエスト】とそれぞれの項目でまとまった配列でリクエストが送られていたとします。その配列を【1ユーザーごとの配列(姓・名・年齢)】に変換する自作関数を作りました。

自分が思い出せるように残してあります。改善点等あればアドバイス頂けますと嬉しいです。

yoyaku.jpg

リクエストで送られた配列(姓・名・年齢)でまとまって渡されている

php
$request = [
    'last_name' => [
        0 => '山田',
        1 => '田中',
        2 => '佐藤',
        3 => '鈴木',
    ],
    'first_name' => [
        0 => '太郎',
        1 => '花子',
        2 => '次郎',
        3 => '三郎',
    ],
    'age' => [
        0 => '10',
        1 => '50',
        2 => '20',
        3 => '33',
    ],
];

変換したい形(姓・名・年齢を1ユーザーごとにまとめる)

php
$users = [
    0 => [
        'last_name' => '山田',
        'first_name' => '太郎',
        'age' => '10',
    ],
    1 => [
        'last_name' => '田中',
        'first_name' => '花子',
        'age' => '50',
    ],
    2 => [
        'last_name' => '佐藤',
        'first_name' => '次郎',
        'age' => '20',
    ],
    3 => [
        'last_name' => '鈴木',
        'first_name' => '三郎',
        'age' => '33',
    ],
];

自作関数はコチラ

追記:コメント欄でよりシンプルな書き方を教えて頂きました。詳しくはコメント欄をご確認下さい。

php
//複数requestされた要素をバルクインサートできるように配列をまとめた関数
function multi_request($request, ...$element)
{
    //後にarray_mergeするので格納する箱を定義
    $elements = [];

    //(要素の数-1)回ループ
    $element_count = (count($request[$element[0]]) - 1);
    for ($i = 0; $i <= $element_count; $i++) {
        foreach ($element as $value) {
            //[要素 => requestされた値]
            $element_value = [
                $value => $request[$value][$i]
            ];
            //引数で指定された要素を配列に格納
            $elements = array_merge($elements, $element_value);
        }
        $mulch_request[] = $elements;
    }
    return $mulch_request;
}

引数は、リクエストされた配列と、それぞれの要素を指定します。この例の場合は姓・名・年齢。
引数は可変のため、3つ以上の指定も可能。

php
$users =multi_request($request, 'last_name', 'first_name', 'age');

動作確認

メモ

コメント欄で頂いたやり方のおさらい。

array_map⇒配列のすべての要素に対して同じ処理を一括で適用
アロー関数⇒関数を引数として渡す場合で直接関数を記述する場合などに使用する

array_mapとアロー関数を使っていろいろ試してみる

array_mapとアロー関数を使った簡単な例

⇒引数の配列の値を2倍にして返す

php
$number = [1, 2, 3];
$double = array_map(fn ($value) => $value * 2, $number);
var_dump($double);

array_mapとアロー関数を使った簡単な例2

引数で...$(2次元配列)を指定すると値のループ操作ができるようです。しかしfn($array)と指定したため1番最初の姓の配列しか処理が適用されませんでした。

下例:引数の配列の値の末尾に「テスト」を追記して$value配列に格納

php
$array = [
    0 => [
        0 => '山田',
        1 => '田中',
        2 => '佐藤',
        3 => '鈴木',
    ],
    1 => [
        0 => '太郎',
        1 => '花子',
        2 => '次郎',
        3 => '三郎',
    ],
    2 => [
        0 => '10',
        1 => '50',
        2 => '20',
        3 => '33',
    ],
];
$test = array_map(fn ($value) => $value.'テスト', ...$array);
var_dump($test);

array(4) {
  [0]=>
  string(15) "山田テスト"
  [1]=>
  string(15) "田中テスト"
  [2]=>
  string(15) "佐藤テスト"
  [3]=>
  string(15) "鈴木テスト"
}

array_mapとアロー関数を使った簡単な例3

例2ではfn($value)となっていたため、引数の$arrayの1番最初の配列のみしか処理がされない。
2番目以降もループ処理するにはfn(...$value)と指定するようです。

php
$array = [
    0 => [
        0 => '山田',
        1 => '田中',
        2 => '佐藤',
        3 => '鈴木',
    ],
    1 => [
        0 => '太郎',
        1 => '花子',
        2 => '次郎',
        3 => '三郎',
    ],
    2 => [
        0 => '10',
        1 => '50',
        2 => '20',
        3 => '33',
    ],
];
$test = array_map(fn (...$value) => $value, ...$array);
var_dump($test);

array(4) {
  [0]=>
  array(3) {
    [0]=>
    string(6) "山田"
    [1]=>
    string(6) "太郎"
    [2]=>
    string(2) "10"
  }
  [1]=>
  array(3) {
    [0]=>
    string(6) "田中"
    [1]=>
    string(6) "花子"
    [2]=>
    string(2) "50"
  }
  [2]=>
  array(3) {
    [0]=>
    string(6) "佐藤"
    [1]=>
    string(6) "次郎"
    [2]=>
    string(2) "20"
  }
  [3]=>
  array(3) {
    [0]=>
    string(6) "鈴木"
    [1]=>
    string(6) "三郎"
    [2]=>
    string(2) "33"
  }
}

コメント欄で頂いたarray_mapとアロー関数を使用したやり方

php
        function combine(array $array): array
        {
            $keys = array_keys($array);
            return array_map(fn (...$values) => array_combine($keys, $values), ...array_values($array));
        }

最後に

ループ処理というとfor文だったり、foreachという発想しかなかったですが、こういったやり方もあるんですね。複数の配列が絡んだループ処理をする際に便利だと思いました。最終的に本投稿の最初の内容からずれてarray_mapとアロー関数の内容となってしましましたが、勉強になりました。このたびはコメントをしていただいた方々には大変感謝しております。ありがとうございました。

0
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0