- カテゴリ: collection
- 対応バージョン: Laravel 12・PHP 8.4
- 名前空間 / FQCN / コマンド:
Illuminate\Support\Collection::collapseWithKeys() - 関連: collapse / flatten / flatMap / mapWithKeys / merge
- 変更履歴: Laravel 11.20で追加。12.0.1で空コレクション時のエラーを修正(空コレクションを返す)。(Laravel News, Laravel Versions)
要点(TL;DR)
- 何に使うか:
[[key=>...], [key=>...]]の1段だけを潰して、内側のキーを保ったまま結合する。 - 最低限の使い方:
collect($rows)->collapseWithKeys(); - よくある罠:
- 入力が既にフラット(内側が配列/コレクションでない)だと空を返す
- 再帰結合ではない(同一キーは後勝ちで置き換え)
- 数値キーは上書きされやすい(穴あきインデックスに注意)(laravel.com, fossies.org, php.net)
概要
collapseWithKeys()は、コレクションの各要素が配列またはコレクションであるとき、それらを1つの連想配列にキーを保持して結合します。collapse()がキーを捨てて平坦化するのに対し、こちらは内側のキーをそのまま残します。入力がフラットな場合は空のコレクションを返します。(laravel.com)
構文 / シグネチャ
/**
* Collapse the collection while preserving inner keys.
*
* @return \Illuminate\Support\Collection
*/
public function Illuminate\Support\Collection::collapseWithKeys(): static;
- 引数
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
| なし | — | — | — | 各要素は配列またはCollectionであること |
- 戻り値:
Collection(内側のキーを保持した結合結果) - 例外/副作用:12.0.1以降は空入力でも例外なし(空を返す)。同一キーは後勝ちで置換(
array_replace相当)。(installatron.com, fossies.org, php.net)
使用例
最小例
use Illuminate\Support\Collection;
$collection = collect([
['first' => collect([1, 2, 3])],
['second' => [4, 5, 6]],
['third' => collect([7, 8, 9])],
]);
$result = $collection->collapseWithKeys()->all();
// ['first'=>[1,2,3], 'second'=>[4,5,6], 'third'=>[7,8,9]]
実務例:モジュール設定の上書きマージ(後勝ち)
use Illuminate\Support\Collection;
$modules = collect([
['features' => ['upload' => true, 'resize' => false]],
['features' => ['resize' => true, 'watermark' => true]], // 後勝ちで上書き
]);
$config = $modules->collapseWithKeys(); // ['features' => ['upload'=>true,'resize'=>true,'watermark'=>true]]
重複キーの上書き確認
$rows = collect([
['map' => ['a' => 1, 'b' => 2]],
['map' => ['b' => 20, 'c' => 30]], // 'b' は上書き
]);
$merged = $rows->collapseWithKeys()->get('map'); // ['a'=>1, 'b'=>20, 'c'=>30]
(後勝ちはarray_replaceの仕様)(php.net)
よくある落とし穴・注意
- フラット入力→空:各要素が配列/
Collectionでないと空を返します。必要ならmap(fn($x)=>[$key=>$x])やwrap()で形を整える。(laravel.com) - 非再帰:多段配列は深い階層をマージしない。再帰的に結合したいなら
Arr::setや独自ロジックを検討。(php.net) - 数値キーの上書き:数値キー同士は位置で置換され、穴あきや上書きが起こる。順序配列なら
collapse()またはvalues()の活用を。(php.net) - エラー挙動:12.0.1以前で空入力時に
ArgumentCountErrorが出る報告があったが修正済み。(GitHub, installatron.com)
代替・関連APIとの比較
- collapse:キーを捨てて値を連結(順序重視のリスト向け)。
- flatten:深さ指定で再帰的に平坦化(キーは基本捨てる)。
- flatMap:変換しながら1段潰す(キーは関数次第)。
- mapWithKeys:自前でキー生成して構築(柔軟だがコスト高)。
- merge:2配列/コレクションを結合(キー保持。複数段は自前で繰り返し)。
選定基準:内側のキーを保って1段だけまとめたい→collapseWithKeys。順序を保って並べたい→collapse。キー生成が必要→mapWithKeys。(laravel.com)
コレクション特性(カテゴリ追加ルール)
- チェーン可否:可(非破壊的/新インスタンスを返す)
- 破壊的/非破壊:非破壊
- キー保持:内側のキーを保持(上書きは後勝ち)
- LazyCollection:対応(
LazyCollection::collapseWithKeys()あり) - 計算量の目安:O(N)(要素総数)。内部で
array_replace一回。(fossies.org)
入出力対応(ミニサンプル)
| 入力(外側) | 各要素の型 | 出力 |
|---|---|---|
[['k'=>[1]], ['x'=>[2]]] | 配列 | ['k'=>[1],'x'=>[2]] |
[['k'=>collect([1])]] | Collection | ['k'=>[1]] |
['a','b','c'] | スカラ | [](空) |
テスト例(Pest)
use Illuminate\Support\Collection;
it('collapses with keys and overrides later', function () {
$c = collect([
['m' => ['a' => 1, 'b' => 2]],
['m' => ['b' => 20]],
]);
$r = $c->collapseWithKeys();
expect($r->get('m'))->toEqual(['a' => 1, 'b' => 20]);
});
it('returns empty when already flat', function () {
expect(collect(['a','b'])->collapseWithKeys()->isEmpty())->toBeTrue();
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
| 期待した結果が空になる | 入力がフラット(内側が配列/Collectionでない) | 事前にmap()で[$key=>$value]の形へ整形 |
| 値が消えた/上書きされた | 同一キーが複数回出現(後勝ち) | マージ順を見直す/キー重複を避ける |
| 数値キーで欠番が出る | array_replaceの仕様で数値キーは位置置換 | 連番化が必要ならvalues()を併用 |
(旧)ArgumentCountError | 空入力時の既知問題(12.0.1で修正) | Laravelを更新(≥12.0.1) (GitHub, installatron.com) |
参考リンク
- Laravel公式「Collections」— collapseWithKeys(12.x) (laravel.com)
- Laravel News「Laravel 11.20」—
collapseWithKeys()追加の紹介 (Laravel News) - フレームワーク実装(
Collection::collapseWithKeysソース) (fossies.org) - PHP:
array_replace仕様(後勝ちの置換) (php.net) - Laravel Versions(12.0.0/12.0.1の変更点概要) (Laravel Versions, installatron.com)
