Laravelのコレクション(その11:内容表示/その他)

0
79

Laravelコレクション掘り下げシリーズ第十一弾(最終回)。今回はコレクションの内容を表示するメソッド、および分類がし難いメソッドに関して確認していきます。

dd

$col1 = collect([1,2,3,4,5],);
$col1->dd();

$col1->push(6);
$col1->dd();

コレクションの内容を表示し、処理を中断します。
結果は以下の通り。

Illuminate\Support\Collection^ {#95
  #items: array:5 [
    0 => 1
    1 => 2
    2 => 3
    3 => 4
    4 => 5
  ]
}

1つ目のddで処理が中断されてしまうため、それ以降の処理は実行されません。

dump

$col1 = collect([1,2,3,4,5],);
$col1->dump();

$col1->push(6);
$col1->dump();

コレクションの内容を表示します。ddと異なり処理は中断されません。
結果は以下の通り。

Illuminate\Support\Collection^ {#93
  #items: array:5 [
    0 => 1
    1 => 2
    2 => 3
    3 => 4
    4 => 5
  ]
}
Illuminate\Support\Collection^ {#93
  #items: array:6 [
    0 => 1
    1 => 2
    2 => 3
    3 => 4
    4 => 5
    5 => 6
  ]
}

push実行後の内容に関しても出力されています。

implode

$col1 = collect([1,2,3,4,5]);
$result = $col1->implode('-'); // 1-2-3-4-5

引数で指定した文字列で要素を連結した結果の文字列を返します。
多次元配列の場合は第一引数で対象となる要素を示すキーを指定し、第二引数に連結用の文字列を指定します。

$col1 = collect([
    [
        [
            1,
            2
        ],
        [
            3,
            4
        ],
    ],
    [
        [
            5,
            6
        ],
        [
            7,
            8
        ],
    ],
]);
$result = $col1->implode('1.0','&'); // 3&7

当然ながらキーは文字列でも問題ありません。

$col1 = collect([
    [
        'item1' => [
            'item1-1' => 1,
            'item1-2' => 2
        ],
        'item2' => [
            'item2-1' => 3,
            'item2-2' => 4
        ],
    ],
    [
        'item1' => [
            'item1-1' => 5,
            'item1-2' => 6
        ],
        'item2' => [
            'item2-1' => 7,
            'item2-2' => 8
        ],
    ],
]);
$result = $col1->implode('item1.item1-2','and'); // 2and6

該当するキーがなかった場合はどうなるでしょう?

$col1 = collect([
    [
        'key1' => 1,
    ],
    [
        'key2' => 2,
    ],
    [
        'key1' => 3,
    ],
]);
$result = $col1->implode('key1','#'); // 1##3

上記のように無視される訳ではなく、空文字扱いとなるようです。

macro

\Illuminate\Support\Collection::macro('custom', function() {
    dump($this->toArray());
});

$col = collect([
    'key1' => 'val1',
    'key2' => 'val2',
]);
$col->custom();

コレクションに対して独自のメソッドを定義できます。
第一引数は新規に生成するメソッドの名称で、第二引数に実行すべき処理内容(関数)を指定します。関数内では元コレクションは「$this」としてアクセスできるので、従来のコレクションのメソッドなども組み合わせて使いながら独自の処理内容を定義できます。
結果は以下の通り。

array:2 [
  "key1" => "val1"
  "key2" => "val2"
]

独自に定義したメソッド「custom」によってコレクションの内容が出力されました。

pipe

$col = collect([1,2,3]);
$result = $col->pipe(function($collection) {
    return $collection->sum();
}); // 6

当該コレクションをコールバックに渡し、コールバックの処理結果が返されます。
と言うことなんですが、これだったら直接以下のように処理しちゃえば良くなります。

$result = $col->sum(); // 6

使い所が今一つイメージしづらい機能です。

reduce

$col = collect([1,2,3]);
$result = $col->reduce(function($total, $val) {
    return $total + ($val * $val);
}); // 14

全要素に対して引数で指定したコールバックを呼び出しますが、前の要素に対するコールバック実行の戻りが次の要素に対するコールバック呼び出し時の第一引数になり、第二引数に当該要素が渡されます。
全ての要素に対するコールバックの実行結果が本メソッドの戻り値になります。
最初の要素に対するコールバック呼び出し時の第一引数はnullですが、reduceの第二引数に値を指定するとそれがコールバックの第一引数の初期値になります。

$col = collect([1,2,3]);
$result = $col->reduce(function($total, $val) {
    return $total + ($val * $val);
}, 10); // 24

tap

$col = collect([1,2,3]);
$col->tap(function($collection) {
    $collection->push(4)->dump();
})->dump();

指定したコールバックに自身が引数として渡されるのでコールバック内で当該コレクションに対して様々な操作が可能ですが、その結果はコレクション本体に影響を与えません。
上記結果は以下のようになります。

(コールバック内のdump結果)
Illuminate\Support\Collection^ {#444
  #items: array:4 [
    0 => 1
    1 => 2
    2 => 3
    3 => 4
  ]
}
(コレクション自体のdump結果)
Illuminate\Support\Collection^ {#445
  #items: array:3 [
    0 => 1
    1 => 2
    2 => 3
  ]
}

おそらくはメソッドチェーンの途中段階の状態をログに残したい場合などに使用するんだと思いますが、あまり使わなそうな予感がします…

総括

implodeはPHP自体にも同様の関数が存在し、こちらは時々使ったりしますので、使い所はありそうな気がします。
dd、dumpはテスト用ですかね。
その他のメソッドに関しては、あまり利用局面が思いつきません。
macroに関しては使う機会があるかもしれませんが、優先度的には、まずはコレクションオリジナルのメソッドが使いこなせるようになるべきかと。

今回でLaravel(6.x)に関するコレクションを一通り確認したことになります。
確認と並行して日常の開発業務の中でもできるだけ学習したメソッドを使うように心がけており、なんとなく開発効率もアップしているような気がします。
ただ、まだまだ資料を見ながらでないと使えない傾向はあるため、早く自分の頭にある知識だけで各種メソッドを使いこなせるように今後も精進したいと思います。