collapseWithKeys — 配列を1段だけ潰してキーを保持したまま結合

  • カテゴリ: 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]]

(laravel.com)

実務例:モジュール設定の上書きマージ(後勝ち)

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)
レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする