Laravelでtranspose

  • 8
    Like
  • 0
    Comment

Transposeとは

Rubyなどでは標準で実装されている。

before.php
[
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9],
]

このような配列を

after.php
[
  [1, 4, 7],
  [2, 5, 8],
  [3, 6, 9],
]

こうする処理。超便利

こんな時に便利Transpose

以下のような追加可能なフォームを実装するときに泣くほど便利です!

form.gif

実装

実装場所はメソッドが使われる以前に読み込まれる場所であればどこでもいいですが、
php artisan make:providerコマンドを使って
CollectionMacroServiceProvider.phpって感じのものを作って実装すると良いでしょう。
メンドくさければAppServiceProvider.phpに書いちゃうのもありです。

CollectionMacroServiceProvider.php
// 同じ名前のメソッドが存在しないかチェック
if (! Collection::hasMacro('transpose')) {
    /*
     * Transpose an array.
     *
     * @return \Illuminate\Support\Collection
     */
    Collection::macro('transpose', function () {
        $items = array_map(function (...$items) {
            return $items;
        }, ...$this->values());

        return new static($items);
    });
}

呼び出し


// 必要な要素だけ取得
$before = collect($input_data)->only('name', 'email', 'address');

// transpose実行
$after = $before->transpose()->map(function ($data) {
    return [
        'name' => $data['0'],
        'email' => $data['1'],
        'address' => $data['2'],
    ];
});

// transpose前
dd($before);
// [
//     ['田中', '鈴木', '佐藤'],
//     ['aaa@example.com', 'bbb@example.com', 'ccc@example.com'],
//     ['東京', '大阪','福岡'],
// ];

// transpose後
dd($after);
// [
//     ['田中', 'aaa@example.com', '東京'],
//     ['鈴木', 'bbb@example.com', '大阪'],
//     ['佐藤', 'ccc@example.com','福岡'],
// ];

参考

https://adamwathan.me/2016/04/06/cleaning-up-form-input-with-transpose/

composerで入れれば楽だし他にも便利なメソッドたくさん使えます!
https://github.com/spatie/laravel-collection-macros