#はじめに
Illuminate\Support\Collection クラスは、配列データを扱うための流暢で便利なラッパーを提供します。例えば、以下のコードをご覧ください。collect ヘルパーを使って配列から新しいコレクションインスタンスを作成し、各要素に strtoupper 関数を適用し、空の要素をすべて除外します:
$collection = collect(['taylor', 'abigail', null])->map(function (?string $name) {
return strtoupper($name);
})->reject(function (string $name) {
return empty($name);
});
ご覧の通り、Collection クラスはメソッドをチェーンして、基になる配列の流暢なマッピングや集約を行えます。一般的に、コレクションはイミュータブルであり、すべての Collection メソッドは新しい Collection インスタンスを返します。
#コレクションの作成
前述の通り、collect ヘルパーは指定した配列から新しい Illuminate\Support\Collection インスタンスを返します。つまり、コレクションの作成は以下のように簡単です:
$collection = collect([1, 2, 3]);
Eloquent のクエリ結果は常に Collection インスタンスとして返されます。
#コレクションの拡張
コレクションは「マクロ可能(macroable)」であり、実行時に Collection クラスに追加のメソッドを追加できます。Illuminate\Support\Collection クラスの macro メソッドは、マクロが呼ばれたときに実行されるクロージャを受け取ります。マクロのクロージャは $this を使ってコレクションの他のメソッドにアクセスでき、まるでコレクションクラスの本物のメソッドのように振る舞います。例えば、以下のコードは Collection クラスに toUpper メソッドを追加します:
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
Collection::macro('toUpper', function () {
return $this->map(function (string $value) {
return Str::upper($value);
});
});
$collection = collect(['first', 'second']);
$upper = $collection->toUpper();
// ['FIRST', 'SECOND']
通常、コレクションマクロは サービスプロバイダー の boot メソッド内で宣言します。
#マクロの引数
必要に応じて、追加の引数を受け取るマクロを定義できます:
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Lang;
Collection::macro('toLocale', function (string $locale) {
return $this->map(function (string $value) use ($locale) {
return Lang::get($value, [], $locale);
});
});
$collection = collect(['first', 'second']);
$translated = $collection->toLocale('es');
#利用可能なメソッド
残りのコレクションのドキュメントでは、Collection クラスで利用できる各メソッドについて説明します。これらのメソッドはすべてチェーン可能で、基になる配列を流暢に操作できます。さらに、ほとんどのメソッドは新しい Collection インスタンスを返すため、必要に応じて元のコレクションを保持できます:
all average avg chunk chunkWhile collapse collect combine concat contains containsOneItem containsStrict count countBy crossJoin dd diff diffAssoc diffAssocUsing diffKeys doesntContain dot dump duplicates duplicatesStrict each eachSpread ensure every except filter first firstOrFail firstWhere flatMap flatten flip forget forPage get groupBy has hasAny implode intersect intersectAssoc intersectByKeys isEmpty isNotEmpty join keyBy keys last lazy macro make map mapInto mapSpread mapToGroups mapWithKeys max median merge mergeRecursive min mode nth only pad partition percentage pipe pipeInto pipeThrough pluck pop prepend pull push put random range reduce reduceSpread reject replace replaceRecursive reverse search select shift shuffle skip skipUntil skipWhile slice sliding sole some sort sortBy sortByDesc sortDesc sortKeys sortKeysDesc sortKeysUsing splice split splitIn sum take takeUntil takeWhile tap times toArray toJson transform undot union unique uniqueStrict unless unlessEmpty unlessNotEmpty unwrap value values when whenEmpty whenNotEmpty where whereStrict whereBetween whereIn whereInStrict whereInstanceOf whereNotBetween whereNotIn whereNotInStrict whereNotNull whereNull wrap zip
#メソッド一覧
<style> .collection-method code { font-size: 14px; } .collection-method:not(.first-collection-method) { margin-top: 50px; } </style>#all() {.collection-method .first-collection-method}
all メソッドはコレクションが表す基の配列を返します:
collect([1, 2, 3])->all();
// [1, 2, 3]
#average() {.collection-method}
avg メソッドのエイリアスです。
#avg() {.collection-method}
avg メソッドは指定したキーの平均値を返します:
$average = collect([
['foo' => 10],
['foo' => 10],
['foo' => 20],
['foo' => 40]
])->avg('foo');
// 20
$average = collect([1, 1, 2, 4])->avg();
// 2
#chunk() {.collection-method}
chunk メソッドはコレクションを指定したサイズの複数の小さなコレクションに分割します:
$collection = collect([1, 2, 3, 4, 5, 6, 7]);
$chunks = $collection->chunk(4);
$chunks->all();
// [[1, 2, 3, 4], [5, 6, 7]]
このメソッドは、Bootstrap のようなグリッドシステムを使う ビュー で特に便利です。例えば、グリッドで表示したい Eloquent モデルのコレクションがある場合を想像してください:
@foreach ($products->chunk(3) as $chunk)
<div class="row">
@foreach ($chunk as $product)
<div class="col-xs-4">{{ $product->name }}</div>
@endforeach
</div>
@endforeach
#chunkWhile() {.collection-method}
chunkWhile メソッドは、指定したコールバックの評価に基づいてコレクションを複数の小さなコレクションに分割します。クロージャに渡される $chunk 変数で前の要素を確認できます:
$collection = collect(str_split('AABBCCCD'));
$chunks = $collection->chunkWhile(function (string $value, int $key, Collection $chunk) {
return $value === $chunk->last();
});
$chunks->all();
// [['A', 'A'], ['B', 'B'], ['C', 'C', 'C'], ['D']]
#collapse() {.collection-method}
collapse メソッドは配列のコレクションを単一のフラットなコレクションにまとめます:
$collection = collect([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]);
$collapsed = $collection->collapse();
$collapsed->all();
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
#collect() {.collection-method}
collect メソッドは現在のコレクションのアイテムを持つ新しい Collection インスタンスを返します:
$collectionA = collect([1, 2, 3]);
$collectionB = $collectionA->collect();
$collectionB->all();
// [1, 2, 3]
collect メソッドは主に レイジーコレクション を標準の Collection インスタンスに変換する際に便利です:
$lazyCollection = LazyCollection::make(function () {
yield 1;
yield 2;
yield 3;
});
$collection = $lazyCollection->collect();
$collection::class;
// 'Illuminate\Support\Collection'
$collection->all();
// [1, 2, 3]
collect メソッドは Enumerable のインスタンスを持っていて、非レイジーなコレクションインスタンスが必要な場合に特に便利です。collect() は Enumerable 契約の一部なので、安全に Collection インスタンスを取得できます。
#combine() {.collection-method}
combine メソッドはコレクションの値をキーとして、別の配列やコレクションの値と組み合わせます:
$collection = collect(['name', 'age']);
$combined = $collection->combine(['George', 29]);
$combined->all();
// ['name' => 'George', 'age' => 29]
#concat() {.collection-method}
concat メソッドは、与えられた array またはコレクションの値を別のコレクションの末尾に追加します:
$collection = collect(['John Doe']);
$concatenated = $collection->concat(['Jane Doe'])->concat(['name' => 'Johnny Doe']);
$concatenated->all();
// ['John Doe', 'Jane Doe', 'Johnny Doe']
concat メソッドは元のコレクションに連結されたアイテムのキーを数値で再インデックスします。連想配列のキーを維持したい場合は、merge メソッドを参照してください。
#contains() {.collection-method}
contains メソッドは、コレクションが指定された項目を含むかどうかを判定します。contains メソッドにクロージャを渡して、コレクション内に指定した条件を満たす要素が存在するかどうかを判定できます:
$collection = collect([1, 2, 3, 4, 5]);
$collection->contains(function (int $value, int $key) {
return $value > 5;
});
// false
代わりに、contains メソッドに文字列を渡して、コレクションに特定の値が含まれているかどうかを判定できます:
$collection = collect(['name' => 'Desk', 'price' => 100]);
$collection->contains('Desk');
// true
$collection->contains('New York');
// false
また、contains メソッドにキーと値のペアを渡して、そのペアがコレクションに存在するかどうかを判定できます:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
]);
$collection->contains('product', 'Bookcase');
// false
contains メソッドは値の比較に「ゆるい」比較を使います。つまり、整数値の文字列は同じ値の整数と等しいとみなされます。厳密な比較を行いたい場合は、containsStrict メソッドを使ってください。
contains の逆の動作は、doesntContain メソッドを参照してください。
#containsOneItem() {.collection-method}
containsOneItem メソッドは、コレクションに単一のアイテムが含まれているかどうかを判定します:
collect([])->containsOneItem();
// false
collect(['1'])->containsOneItem();
// true
collect(['1', '2'])->containsOneItem();
// false
#containsStrict() {.collection-method}
このメソッドはcontainsメソッドと同じシグネチャですが、すべての値を「厳密」比較で判定します。
このメソッドの動作はEloquent Collections使用時に変更されます。
#count() {.collection-method}
count メソッドはコレクション内のアイテム数を返します:
$collection = collect([1, 2, 3, 4]);
$collection->count();
// 4
#countBy() {.collection-method}
countBy メソッドはコレクション内の値の出現回数を数えます。デフォルトではすべての要素の出現回数を数え、特定の「種類」の要素数をカウントできます:
$collection = collect([1, 2, 2, 2, 3]);
$counted = $collection->countBy();
$counted->all();
// [1 => 1, 2 => 3, 3 => 1]
countBy メソッドにクロージャを渡して、カスタム値でアイテムをカウントできます:
$collection = collect(['[email protected]', '[email protected]', '[email protected]']);
$counted = $collection->countBy(function (string $email) {
return substr(strrchr($email, "@"), 1);
});
$counted->all();
// ['gmail.com' => 2, 'yahoo.com' => 1]
#crossJoin() {.collection-method}
crossJoin メソッドは、指定した配列やコレクションとコレクションの値をクロス結合し、すべての組み合わせのデカルト積を返します:
$collection = collect([1, 2]);
$matrix = $collection->crossJoin(['a', 'b']);
$matrix->all();
/*
[
[1, 'a'],
[1, 'b'],
[2, 'a'],
[2, 'b'],
]
*/
$collection = collect([1, 2]);
$matrix = $collection->crossJoin(['a', 'b'], ['I', 'II']);
$matrix->all();
/*
[
[1, 'a', 'I'],
[1, 'a', 'II'],
[1, 'b', 'I'],
[1, 'b', 'II'],
[2, 'a', 'I'],
[2, 'a', 'II'],
[2, 'b', 'I'],
[2, 'b', 'II'],
]
*/
#dd() {.collection-method}
dd メソッドはコレクションのアイテムをダンプし、スクリプトの実行を終了します:
$collection = collect(['John Doe', 'Jane Doe']);
$collection->dd();
/*
Collection {
#items: array:2 [
0 => "John Doe"
1 => "Jane Doe"
]
}
*/
スクリプトの実行を停止したくない場合は、代わりにdumpメソッドを使ってください。
#diff() {.collection-method}
diff メソッドは、コレクションの値を別のコレクションや通常の PHP array と比較します。このメソッドは、元のコレクションにあって指定したコレクションに存在しない値を返します:
$collection = collect([1, 2, 3, 4, 5]);
$diff = $collection->diff([2, 4, 6, 8]);
$diff->all();
// [1, 3, 5]
このメソッドの動作はEloquent Collections使用時に変更されます。
#diffAssoc() {.collection-method}
diffAssoc メソッドは、キーと値の両方を基に別のコレクションや通常の PHP array と比較します。このメソッドは、元のコレクションにあって指定したコレクションに存在しないキーと値のペアを返します:
$collection = collect([
'color' => 'orange',
'type' => 'fruit',
'remain' => 6,
]);
$diff = $collection->diffAssoc([
'color' => 'yellow',
'type' => 'fruit',
'remain' => 3,
'used' => 6,
]);
$diff->all();
// ['color' => 'orange', 'remain' => 6]
#diffAssocUsing() {.collection-method}
diffAssoc と異なり、diffAssocUsing はキーの比較にユーザー指定のコールバック関数を受け取ります:
$collection = collect([
'color' => 'orange',
'type' => 'fruit',
'remain' => 6,
]);
$diff = $collection->diffAssocUsing([
'Color' => 'yellow',
'Type' => 'fruit',
'Remain' => 3,
], 'strnatcasecmp');
$diff->all();
// ['color' => 'orange', 'remain' => 6]
コールバックは、0未満、0、0より大きい整数を返す比較関数である必要があります。詳細は PHP の array_diff_uassoc のドキュメントを参照してください。diffAssocUsing は内部的にこの PHP 関数を利用しています。
#diffKeys() {.collection-method}
diffKeys メソッドは、キーを基に別のコレクションや通常の PHP array と比較します。このメソッドは、元のコレクションにあって指定したコレクションに存在しないキーと値のペアを返します:
$collection = collect([
'one' => 10,
'two' => 20,
'three' => 30,
'four' => 40,
'five' => 50,
]);
$diff = $collection->diffKeys([
'two' => 2,
'four' => 4,
'six' => 6,
'eight' => 8,
]);
$diff->all();
// ['one' => 10, 'three' => 30, 'five' => 50]
#doesntContain() {.collection-method}
doesntContain メソッドは、コレクションが指定したアイテムを含まないかどうかを判定します。要素が指定した真偽テストに一致するものがコレクションに存在しないかを判定するために、doesntContain メソッドにクロージャを渡せます:
$collection = collect([1, 2, 3, 4, 5]);
$collection->doesntContain(function (int $value, int $key) {
return $value < 5;
});
// false
代わりに、doesntContain メソッドに文字列を渡して、コレクションに特定の値が含まれていないかを判定できます:
$collection = collect(['name' => 'Desk', 'price' => 100]);
$collection->doesntContain('Table');
// true
$collection->doesntContain('Desk');
// false
また、doesntContain メソッドにキーと値のペアを渡して、そのペアがコレクションに存在しないかを判定できます:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
]);
$collection->doesntContain('product', 'Bookcase');
// true
doesntContain メソッドは値の比較に「ゆるい」比較を使います。つまり、整数値の文字列は同じ値の整数と等しいとみなされます。
#dot() {.collection-method}
dot メソッドは多次元のコレクションをフラット化し、深さを示すために「ドット」表記を使った単一レベルのコレクションに変換します:
$collection = collect(['products' => ['desk' => ['price' => 100]]]);
$flattened = $collection->dot();
$flattened->all();
// ['products.desk.price' => 100]
#dump() {.collection-method}
dump メソッドはコレクションのアイテムをダンプします:
$collection = collect(['John Doe', 'Jane Doe']);
$collection->dump();
/*
Collection {
#items: array:2 [
0 => "John Doe"
1 => "Jane Doe"
]
}
*/
ダンプ後にスクリプトの実行を停止したい場合は、代わりにddメソッドを使ってください。
#duplicates() {.collection-method}
duplicates メソッドはコレクション内の重複する値を取得して返します:
$collection = collect(['a', 'b', 'a', 'c', 'b']);
$collection->duplicates();
// [2 => 'a', 4 => 'b']
コレクションに配列やオブジェクトが含まれている場合、重複チェックしたい属性のキーを渡せます:
$employees = collect([
['email' => '[email protected]', 'position' => 'Developer'],
['email' => '[email protected]', 'position' => 'Designer'],
['email' => '[email protected]', 'position' => 'Developer'],
]);
$employees->duplicates('position');
// [2 => 'Developer']
#duplicatesStrict() {.collection-method}
このメソッドはduplicatesメソッドと同じシグネチャですが、すべての値を「厳密」比較で判定します。
#each() {.collection-method}
each メソッドはコレクションのアイテムを繰り返し処理し、各アイテムをクロージャに渡します:
$collection = collect([1, 2, 3, 4]);
$collection->each(function (int $item, int $key) {
// ...
});
繰り返し処理を途中で止めたい場合は、クロージャから false を返せます:
$collection->each(function (int $item, int $key) {
if (/* condition */) {
return false;
}
});
#eachSpread() {.collection-method}
eachSpread メソッドはコレクションのアイテムを繰り返し処理し、各ネストされたアイテムの値をコールバックに渡します:
$collection = collect([['John Doe', 35], ['Jane Doe', 33]]);
$collection->eachSpread(function (string $name, int $age) {
// ...
});
コールバックから false を返すことで繰り返し処理を停止できます:
$collection->eachSpread(function (string $name, int $age) {
return false;
});
#ensure() {.collection-method}
ensure メソッドは、コレクションのすべての要素が指定した型または型のリストであることを検証します。そうでない場合は UnexpectedValueException をスローします:
return $collection->ensure(User::class);
return $collection->ensure([User::class, Customer::class]);
string、int、float、bool、array のようなプリミティブ型も指定できます:
return $collection->ensure('int');
ensure メソッドは、後から異なる型の要素がコレクションに追加されないことを保証しません。
#every() {.collection-method}
every メソッドは、コレクションのすべての要素が指定した条件を満たすかどうかを検証します:
collect([1, 2, 3, 4])->every(function (int $value, int $key) {
return $value > 2;
});
// false
コレクションが空の場合、every メソッドは true を返します:
$collection = collect([]);
$collection->every(function (int $value, int $key) {
return $value > 2;
});
// true
#except() {.collection-method}
except メソッドは、指定したキーを除いたコレクション内のすべてのアイテムを返します:
$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]);
$filtered = $collection->except(['price', 'discount']);
$filtered->all();
// ['product_id' => 1]
except の逆は、only メソッドを参照してください。
このメソッドの動作はEloquent Collections使用時に変更されます。
#filter() {.collection-method}
filter メソッドは、指定したクロージャを使ってコレクションをフィルタリングし、条件を満たすアイテムだけを保持します:
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->filter(function (int $value, int $key) {
return $value > 2;
});
$filtered->all();
// [3, 4]
コールバックが指定されない場合、false と等価なコレクションのすべての要素が削除されます:
$collection = collect([1, 2, 3, null, false, '', 0, []]);
$collection->filter()->all();
// [1, 2, 3]
filter の逆の操作は、reject メソッドを参照してください。
#first() {.collection-method}
first メソッドは、指定した条件を満たすコレクション内の最初の要素を返します:
collect([1, 2, 3, 4])->first(function (int $value, int $key) {
return $value > 2;
});
// 3
引数なしで first メソッドを呼び出すと、コレクションの最初の要素を取得します。コレクションが空の場合は null が返されます:
collect([1, 2, 3, 4])->first();
// 1
#firstOrFail() {.collection-method}
firstOrFail メソッドは first と同じですが、結果が見つからない場合は Illuminate\Support\ItemNotFoundException 例外をスローします:
collect([1, 2, 3, 4])->firstOrFail(function (int $value, int $key) {
return $value > 5;
});
// ItemNotFoundException をスローします...
引数なしで firstOrFail を呼び出すと、コレクションの最初の要素を取得します。コレクションが空の場合は Illuminate\Support\ItemNotFoundException 例外をスローします:
collect([])->firstOrFail();
// ItemNotFoundException をスローします...
#firstWhere() {.collection-method}
firstWhere メソッドは、指定したキーと値のペアに一致するコレクション内の最初の要素を返します:
$collection = collect([
['name' => 'Regena', 'age' => null],
['name' => 'Linda', 'age' => 14],
['name' => 'Diego', 'age' => 23],
['name' => 'Linda', 'age' => 84],
]);
$collection->firstWhere('name', 'Linda');
// ['name' => 'Linda', 'age' => 14]
比較演算子を使って firstWhere メソッドを呼び出すこともできます:
$collection->firstWhere('age', '>=', 18);
// ['name' => 'Diego', 'age' => 23]
where メソッドと同様に、firstWhere メソッドに引数を1つ渡すことができます。この場合、firstWhere メソッドは、指定したアイテムキーの値が真と評価される最初のアイテムを返します:
$collection->firstWhere('age');
// ['name' => 'Linda', 'age' => 14]
#flatMap() {.collection-method}
flatMap メソッドはコレクションを反復処理し、各値を指定したクロージャに渡します。クロージャはアイテムを変更して返すことができ、その結果、新しい変更済みアイテムのコレクションが作成されます。その後、配列は1レベルだけフラット化されます:
$collection = collect([
['name' => 'Sally'],
['school' => 'Arkansas'],
['age' => 28]
]);
$flattened = $collection->flatMap(function (array $values) {
return array_map('strtoupper', $values);
});
$flattened->all();
// ['name' => 'SALLY', 'school' => 'ARKANSAS', 'age' => '28'];
#flatten() {.collection-method}
flatten メソッドは多次元のコレクションを1次元に平坦化します:
$collection = collect([
'name' => 'taylor',
'languages' => [
'php', 'javascript'
]
]);
$flattened = $collection->flatten();
$flattened->all();
// ['taylor', 'php', 'javascript'];
必要に応じて、flatten メソッドに「深さ」引数を渡すこともできます:
$collection = collect([
'Apple' => [
[
'name' => 'iPhone 6S',
'brand' => 'Apple'
],
],
'Samsung' => [
[
'name' => 'Galaxy S7',
'brand' => 'Samsung'
],
],
]);
$products = $collection->flatten(1);
$products->values()->all();
/*
[
['name' => 'iPhone 6S', 'brand' => 'Apple'],
['name' => 'Galaxy S7', 'brand' => 'Samsung'],
]
*/
この例では、深さを指定せずに flatten を呼び出すと、ネストされた配列もすべて平坦化されて ['iPhone 6S', 'Apple', 'Galaxy S7', 'Samsung'] となります。深さを指定することで、どのレベルまで平坦化するかを制御できます。
#flip() {.collection-method}
flip メソッドはコレクションのキーと値を入れ替えます:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);
$flipped = $collection->flip();
$flipped->all();
// ['taylor' => 'name', 'laravel' => 'framework']
#forget() {.collection-method}
forget メソッドはキーを指定してコレクションからアイテムを削除します:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);
$collection->forget('name');
$collection->all();
// ['framework' => 'laravel']
ほとんどのコレクションメソッドとは異なり、forget は新しい変更済みコレクションを返さず、呼び出されたコレクション自体を変更します。
#forPage() {.collection-method}
forPage メソッドは、指定したページ番号に表示されるアイテムだけを含む新しいコレクションを返します。最初の引数にページ番号、2番目の引数に1ページあたりのアイテム数を指定します:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);
$chunk = $collection->forPage(2, 3);
$chunk->all();
// [4, 5, 6]
#get() {.collection-method}
get メソッドは指定したキーのアイテムを返します。キーが存在しない場合は null を返します:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);
$value = $collection->get('name');
// taylor
オプションで2番目の引数にデフォルト値を渡せます:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);
$value = $collection->get('age', 34);
// 34
メソッドのデフォルト値としてコールバックを渡すこともできます。指定したキーが存在しない場合、コールバックの結果が返されます:
$collection->get('email', function () {
return '[email protected]';
});
// [email protected]
#groupBy() {.collection-method}
groupBy メソッドは、指定したキーでコレクションのアイテムをグループ化します:
$collection = collect([
['account_id' => 'account-x10', 'product' => 'Chair'],
['account_id' => 'account-x10', 'product' => 'Bookcase'],
['account_id' => 'account-x11', 'product' => 'Desk'],
]);
$grouped = $collection->groupBy('account_id');
$grouped->all();
/*
[
'account-x10' => [
['account_id' => 'account-x10', 'product' => 'Chair'],
['account_id' => 'account-x10', 'product' => 'Bookcase'],
],
'account-x11' => [
['account_id' => 'account-x11', 'product' => 'Desk'],
],
]
*/
文字列の key の代わりにコールバックを渡すこともできます。コールバックはグループ化に使う値を返す必要があります:
$grouped = $collection->groupBy(function (array $item, int $key) {
return substr($item['account_id'], -3);
});
$grouped->all();
/*
[
'x10' => [
['account_id' => 'account-x10', 'product' => 'Chair'],
['account_id' => 'account-x10', 'product' => 'Bookcase'],
],
'x11' => [
['account_id' => 'account-x11', 'product' => 'Desk'],
],
]
*/
複数のグループ化条件を配列で渡すこともできます。配列の各要素は多次元配列の対応するレベルに適用されます:
$data = new Collection([
10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],
20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],
30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']],
40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],
]);
$result = $data->groupBy(['skill', function (array $item) {
return $item['roles'];
}], preserveKeys: true);
/*
[
1 => [
'Role_1' => [
10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],
20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],
],
'Role_2' => [
20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],
],
'Role_3' => [
10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],
],
],
2 => [
'Role_1' => [
30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']],
],
'Role_2' => [
40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],
],
],
];
*/
#has() {.collection-method}
has メソッドは、指定したキーがコレクションに存在するかどうかを判定します:
$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]);
$collection->has('product');
// true
$collection->has(['product', 'amount']);
// true
$collection->has(['amount', 'price']);
// false
#hasAny() {.collection-method}
hasAny メソッドは、指定したキーのうちいずれかがコレクションに存在するかどうかを判定します:
$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]);
$collection->hasAny(['product', 'price']);
// true
$collection->hasAny(['name', 'price']);
// false
#implode() {.collection-method}
implode メソッドはコレクションのアイテムを連結します。引数はコレクションのアイテムの種類によって異なります。配列やオブジェクトが含まれる場合は、連結したい属性のキーと、値の間に挿入する「区切り文字」を渡します:
$collection = collect([
['account_id' => 1, 'product' => 'Desk'],
['account_id' => 2, 'product' => 'Chair'],
]);
$collection->implode('product', ', ');
// Desk, Chair
コレクションに単純な文字列や数値が含まれる場合は、区切り文字だけを引数に渡します:
collect([1, 2, 3, 4, 5])->implode('-');
// '1-2-3-4-5'
implode メソッドにクロージャを渡して、連結する値のフォーマットをカスタマイズすることもできます:
$collection->implode(function (array $item, int $key) {
return strtoupper($item['product']);
}, ', ');
// DESK, CHAIR
#intersect() {.collection-method}
intersect メソッドは、指定した array またはコレクションに存在しない値を元のコレクションから削除します。結果のコレクションは元のキーを保持します:
$collection = collect(['Desk', 'Sofa', 'Chair']);
$intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']);
$intersect->all();
// [0 => 'Desk', 2 => 'Chair']
このメソッドの挙動は Eloquent Collections 使用時に変更されます。
#intersectAssoc() {.collection-method}
intersectAssoc メソッドは元のコレクションと別のコレクションまたは array を比較し、すべてのコレクションに存在するキーと値のペアを返します:
$collection = collect([
'color' => 'red',
'size' => 'M',
'material' => 'cotton'
]);
$intersect = $collection->intersectAssoc([
'color' => 'blue',
'size' => 'M',
'material' => 'polyester'
]);
$intersect->all();
// ['size' => 'M']
#intersectByKeys() {.collection-method}
intersectByKeys メソッドは、指定した array またはコレクションに存在しないキーとその値を元のコレクションから削除します:
$collection = collect([
'serial' => 'UX301', 'type' => 'screen', 'year' => 2009,
]);
$intersect = $collection->intersectByKeys([
'reference' => 'UX404', 'type' => 'tab', 'year' => 2011,
]);
$intersect->all();
// ['type' => 'screen', 'year' => 2009]
#isEmpty() {.collection-method}
isEmpty メソッドは、コレクションが空の場合に true を返し、それ以外の場合は false を返します:
collect([])->isEmpty();
// true
#isNotEmpty() {.collection-method}
isNotEmpty メソッドは、コレクションが空でない場合に true を返し、空の場合は false を返します:
collect([])->isNotEmpty();
// false
#join() {.collection-method}
join メソッドは、コレクションの値を文字列で結合します。このメソッドの第2引数を使うと、最後の要素をどのように文字列に追加するか指定できます:
collect(['a', 'b', 'c'])->join(', '); // 'a, b, c'
collect(['a', 'b', 'c'])->join(', ', ', and '); // 'a, b, and c'
collect(['a', 'b'])->join(', ', ' and '); // 'a and b'
collect(['a'])->join(', ', ' and '); // 'a'
collect([])->join(', ', ' and '); // ''
#keyBy() {.collection-method}
keyBy メソッドは、指定したキーでコレクションのキーを設定します。同じキーを持つ複数のアイテムがある場合は、最後のアイテムだけが新しいコレクションに含まれます:
$collection = collect([
['product_id' => 'prod-100', 'name' => 'Desk'],
['product_id' => 'prod-200', 'name' => 'Chair'],
]);
$keyed = $collection->keyBy('product_id');
$keyed->all();
/*
[
'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
]
*/
コールバックを渡すこともできます。コールバックは、コレクションのキーに使う値を返す必要があります:
$keyed = $collection->keyBy(function (array $item, int $key) {
return strtoupper($item['product_id']);
});
$keyed->all();
/*
[
'PROD-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
'PROD-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
]
*/
#keys() {.collection-method}
keys メソッドは、コレクションのすべてのキーを返します:
$collection = collect([
'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
]);
$keys = $collection->keys();
$keys->all();
// ['prod-100', 'prod-200']
#last() {.collection-method}
last メソッドは、指定した条件を満たすコレクションの最後の要素を返します:
collect([1, 2, 3, 4])->last(function (int $value, int $key) {
return $value < 3;
});
// 2
引数なしで last メソッドを呼び出すと、コレクションの最後の要素を取得します。コレクションが空の場合は null を返します:
collect([1, 2, 3, 4])->last();
// 4
#lazy() {.collection-method}
lazy メソッドは、元の配列から新しい LazyCollection インスタンスを返します:
$lazyCollection = collect([1, 2, 3, 4])->lazy();
$lazyCollection::class;
// Illuminate\Support\LazyCollection
$lazyCollection->all();
// [1, 2, 3, 4]
大量のアイテムを含む大きな Collection に対して変換処理を行う場合に特に便利です:
$count = $hugeCollection
->lazy()
->where('country', 'FR')
->where('balance', '>', '100')
->count();
LazyCollection に変換することで、大量の追加メモリ割り当てを避けられます。元のコレクションは値をメモリに保持しますが、その後のフィルター処理はそうではありません。したがって、フィルター処理時にほとんど追加メモリが割り当てられません。
#macro() {.collection-method}
静的な macro メソッドを使うと、実行時に Collection クラスにメソッドを追加できます。詳細は extending collections のドキュメントを参照してください。
#make() {.collection-method}
静的な make メソッドは、新しいコレクションインスタンスを作成します。Creating Collections セクションも参照してください。
#map() {.collection-method}
map メソッドはコレクションを繰り返し処理し、各値を指定したコールバックに渡します。コールバックはアイテムを変更して返すことができ、その結果、新しい変更済みアイテムのコレクションが作られます:
$collection = collect([1, 2, 3, 4, 5]);
$multiplied = $collection->map(function (int $item, int $key) {
return $item * 2;
});
$multiplied->all();
// [2, 4, 6, 8, 10]
ほとんどのコレクションメソッドと同様に、map は新しいコレクションインスタンスを返し、元のコレクションは変更しません。元のコレクションを変換したい場合は、transform メソッドを使ってください。
#mapInto() {.collection-method}
mapInto() メソッドはコレクションを繰り返し処理し、値をコンストラクターに渡して指定したクラスの新しいインスタンスを作成します:
class Currency
{
/**
* 新しい通貨インスタンスを作成します。
*/
function __construct(
public string $code
) {}
}
$collection = collect(['USD', 'EUR', 'GBP']);
$currencies = $collection->mapInto(Currency::class);
$currencies->all();
// [Currency('USD'), Currency('EUR'), Currency('GBP')]
#mapSpread() {.collection-method}
mapSpread メソッドはコレクションのアイテムを繰り返し処理し、各ネストされたアイテムの値を指定したクロージャに渡します。クロージャはアイテムを変更して返すことができ、新しい変更済みアイテムのコレクションが作られます:
$collection = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
$chunks = $collection->chunk(2);
$sequence = $chunks->mapSpread(function (int $even, int $odd) {
return $even + $odd;
});
$sequence->all();
// [1, 5, 9, 13, 17]
#mapToGroups() {.collection-method}
mapToGroups メソッドは、指定したクロージャでコレクションのアイテムをグループ化します。クロージャは単一のキーと値のペアを含む連想配列を返し、新しいグループ化されたコレクションを作ります:
$collection = collect([
[
'name' => 'John Doe',
'department' => 'Sales',
],
[
'name' => 'Jane Doe',
'department' => 'Sales',
],
[
'name' => 'Johnny Doe',
'department' => 'Marketing',
]
]);
$grouped = $collection->mapToGroups(function (array $item, int $key) {
return [$item['department'] => $item['name']];
});
$grouped->all();
/*
[
'Sales' => ['John Doe', 'Jane Doe'],
'Marketing' => ['Johnny Doe'],
]
*/
$grouped->get('Sales')->all();
// ['John Doe', 'Jane Doe']
#mapWithKeys() {.collection-method}
mapWithKeys メソッドはコレクションを繰り返し処理し、各値を指定したコールバックに渡します。コールバックは単一のキーと値のペアを含む連想配列を返す必要があります:
$collection = collect([
[
'name' => 'John',
'department' => 'Sales',
'email' => '[email protected]',
],
[
'name' => 'Jane',
'department' => 'Marketing',
'email' => '[email protected]',
]
]);
$keyed = $collection->mapWithKeys(function (array $item, int $key) {
return [$item['email'] => $item['name']];
});
$keyed->all();
/*
[
'[email protected]' => 'John',
'[email protected]' => 'Jane',
]
*/
#max() {.collection-method}
max メソッドは、指定したキーの最大値を返します:
$max = collect([
['foo' => 10],
['foo' => 20]
])->max('foo');
// 20
$max = collect([1, 2, 3, 4, 5])->max();
// 5
#median() {.collection-method}
median メソッドは、指定したキーの中央値を返します:
$median = collect([
['foo' => 10],
['foo' => 10],
['foo' => 20],
['foo' => 40]
])->median('foo');
// 15
$median = collect([1, 1, 2, 4])->median();
// 1.5
#merge() {.collection-method}
merge メソッドは、指定した配列またはコレクションを元のコレクションにマージします。指定したアイテムの文字列キーが元のコレクションの文字列キーと一致する場合、指定したアイテムの値が元の値を上書きします:
$collection = collect(['product_id' => 1, 'price' => 100]);
$merged = $collection->merge(['price' => 200, 'discount' => false]);
$merged->all();
// ['product_id' => 1, 'price' => 200, 'discount' => false]
指定したアイテムのキーが数値の場合、値はコレクションの末尾に追加されます:
$collection = collect(['Desk', 'Chair']);
$merged = $collection->merge(['Bookcase', 'Door']);
$merged->all();
// ['Desk', 'Chair', 'Bookcase', 'Door']
#mergeRecursive() {.collection-method}
mergeRecursive メソッドは、指定した配列またはコレクションを元のコレクションに再帰的にマージします。指定したアイテムの文字列キーが元のコレクションの文字列キーと一致する場合、それらの値は配列にマージされ、再帰的に処理されます:
$collection = collect(['product_id' => 1, 'price' => 100]);
$merged = $collection->mergeRecursive([
'product_id' => 2,
'price' => 200,
'discount' => false
]);
$merged->all();
// ['product_id' => [1, 2], 'price' => [100, 200], 'discount' => false]
#min() {.collection-method}
min メソッドは、指定したキーの最小値を返します:
$min = collect([['foo' => 10], ['foo' => 20]])->min('foo');
// 10
$min = collect([1, 2, 3, 4, 5])->min();
// 1
#mode() {.collection-method}
mode メソッドは、指定したキーの最頻値を返します:
$mode = collect([
['foo' => 10],
['foo' => 10],
['foo' => 20],
['foo' => 40]
])->mode('foo');
// [10]
$mode = collect([1, 1, 2, 4])->mode();
// [1]
$mode = collect([1, 1, 2, 2])->mode();
// [1, 2]
#nth() {.collection-method}
nth メソッドは、n 番目ごとの要素からなる新しいコレクションを作成します:
$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']);
$collection->nth(4);
// ['a', 'e']
第2引数で開始オフセットを指定することもできます:
$collection->nth(4, 1);
// ['b', 'f']
#only() {.collection-method}
only メソッドは、指定したキーのアイテムだけを返します:
$collection = collect([
'product_id' => 1,
'name' => 'Desk',
'price' => 100,
'discount' => false
]);
$filtered = $collection->only(['product_id', 'name']);
$filtered->all();
// ['product_id' => 1, 'name' => 'Desk']
only の逆の動作は、except メソッドを参照してください。
このメソッドの動作は、Eloquent Collections 使用時に変更されます。
#pad() {.collection-method}
pad メソッドは、指定したサイズに達するまで指定した値で配列を埋めます。このメソッドは PHP の array_pad 関数と同様に動作します。
左側にパディングするには、サイズに負の値を指定します。指定したサイズの絶対値が配列の長さ以下の場合はパディングされません:
$collection = collect(['A', 'B', 'C']);
$filtered = $collection->pad(5, 0);
$filtered->all();
// ['A', 'B', 'C', 0, 0]
$filtered = $collection->pad(-5, 0);
$filtered->all();
// [0, 0, 'A', 'B', 'C']
#partition() {.collection-method}
partition メソッドは、PHP の配列分割構文と組み合わせて、指定した条件を満たす要素と満たさない要素を分けることができます:
$collection = collect([1, 2, 3, 4, 5, 6]);
[$underThree, $equalOrAboveThree] = $collection->partition(function (int $i) {
return $i < 3;
});
$underThree->all();
// [1, 2]
$equalOrAboveThree->all();
// [3, 4, 5, 6]
#percentage() {.collection-method}
percentage メソッドは、指定した条件を満たすコレクション内のアイテムの割合を素早く求めるのに使えます:
$collection = collect([1, 1, 2, 2, 2, 3]);
$percentage = $collection->percentage(fn ($value) => $value === 1);
// 33.33
デフォルトでは、パーセンテージは小数点以下2桁に丸められます。ただし、メソッドに第2引数を渡すことでこの動作をカスタマイズできます。
$percentage = $collection->percentage(fn ($value) => $value === 1, precision: 3);
// 33.333
#pipe() {.collection-method}
pipe メソッドはコレクションを指定したクロージャに渡し、実行結果を返します。
$collection = collect([1, 2, 3]);
$piped = $collection->pipe(function (Collection $collection) {
return $collection->sum();
});
// 6
#pipeInto() {.collection-method}
pipeInto メソッドは指定したクラスの新しいインスタンスを作成し、コレクションをコンストラクタに渡します。
class ResourceCollection
{
/**
* 新しい ResourceCollection インスタンスを作成します。
*/
public function __construct(
public Collection $collection,
) {}
}
$collection = collect([1, 2, 3]);
$resource = $collection->pipeInto(ResourceCollection::class);
$resource->collection->all();
// [1, 2, 3]
#pipeThrough() {.collection-method}
pipeThrough メソッドはコレクションを指定したクロージャの配列に順に渡し、最後のクロージャの結果を返します。
use Illuminate\Support\Collection;
$collection = collect([1, 2, 3]);
$result = $collection->pipeThrough([
function (Collection $collection) {
return $collection->merge([4, 5]);
},
function (Collection $collection) {
return $collection->sum();
},
]);
// 15
#pluck() {.collection-method}
pluck メソッドは指定したキーのすべての値を取得します。
$collection = collect([
['product_id' => 'prod-100', 'name' => 'Desk'],
['product_id' => 'prod-200', 'name' => 'Chair'],
]);
$plucked = $collection->pluck('name');
$plucked->all();
// ['Desk', 'Chair']
結果のコレクションのキーを指定することもできます。
$plucked = $collection->pluck('name', 'product_id');
$plucked->all();
// ['prod-100' => 'Desk', 'prod-200' => 'Chair']
pluck メソッドは「ドット」記法を使ってネストされた値の取得もサポートしています。
$collection = collect([
[
'name' => 'Laracon',
'speakers' => [
'first_day' => ['Rosa', 'Judith'],
],
],
[
'name' => 'VueConf',
'speakers' => [
'first_day' => ['Abigail', 'Joey'],
],
],
]);
$plucked = $collection->pluck('speakers.first_day');
$plucked->all();
// [['Rosa', 'Judith'], ['Abigail', 'Joey']]
重複するキーがある場合、最後にマッチした要素が結果のコレクションに挿入されます。
$collection = collect([
['brand' => 'Tesla', 'color' => 'red'],
['brand' => 'Pagani', 'color' => 'white'],
['brand' => 'Tesla', 'color' => 'black'],
['brand' => 'Pagani', 'color' => 'orange'],
]);
$plucked = $collection->pluck('color', 'brand');
$plucked->all();
// ['Tesla' => 'black', 'Pagani' => 'orange']
#pop() {.collection-method}
pop メソッドはコレクションの最後のアイテムを削除して返します。
$collection = collect([1, 2, 3, 4, 5]);
$collection->pop();
// 5
$collection->all();
// [1, 2, 3, 4]
pop メソッドに整数を渡すと、コレクションの末尾から複数のアイテムを削除して返せます。
$collection = collect([1, 2, 3, 4, 5]);
$collection->pop(3);
// collect([5, 4, 3])
$collection->all();
// [1, 2]
#prepend() {.collection-method}
prepend メソッドはコレクションの先頭にアイテムを追加します。
$collection = collect([1, 2, 3, 4, 5]);
$collection->prepend(0);
$collection->all();
// [0, 1, 2, 3, 4, 5]
第2引数にキーを指定して、追加するアイテムのキーを設定できます。
$collection = collect(['one' => 1, 'two' => 2]);
$collection->prepend(0, 'zero');
$collection->all();
// ['zero' => 0, 'one' => 1, 'two' => 2]
#pull() {.collection-method}
pull メソッドはキーを指定してコレクションからアイテムを削除し、その値を返します。
$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']);
$collection->pull('name');
// 'Desk'
$collection->all();
// ['product_id' => 'prod-100']
#push() {.collection-method}
push メソッドはコレクションの末尾にアイテムを追加します。
$collection = collect([1, 2, 3, 4]);
$collection->push(5);
$collection->all();
// [1, 2, 3, 4, 5]
#put() {.collection-method}
put メソッドは指定したキーと値をコレクションに設定します。
$collection = collect(['product_id' => 1, 'name' => 'Desk']);
$collection->put('price', 100);
$collection->all();
// ['product_id' => 1, 'name' => 'Desk', 'price' => 100]
#random() {.collection-method}
random メソッドはコレクションからランダムにアイテムを返します。
$collection = collect([1, 2, 3, 4, 5]);
$collection->random();
// 4 - (ランダムに取得)
random に整数を渡すと、指定した数のアイテムをランダムに取得できます。数を指定した場合は常にコレクションが返されます。
$random = $collection->random(3);
$random->all();
// [2, 4, 5] - (ランダムに取得)
コレクションのアイテム数が要求数より少ない場合、random メソッドは InvalidArgumentException をスローします。
random メソッドはクロージャも受け付け、現在のコレクションインスタンスを渡します。
use Illuminate\Support\Collection;
$random = $collection->random(fn (Collection $items) => min(10, count($items)));
$random->all();
// [1, 2, 3, 4, 5] - (ランダムに取得)
#range() {.collection-method}
range メソッドは指定した範囲内の整数を含むコレクションを返します。
$collection = collect()->range(3, 6);
$collection->all();
// [3, 4, 5, 6]
#reduce() {.collection-method}
reduce メソッドはコレクションを単一の値に集約し、各イテレーションの結果を次のイテレーションに渡します。
$collection = collect([1, 2, 3]);
$total = $collection->reduce(function (?int $carry, int $item) {
return $carry + $item;
});
// 6
最初のイテレーションでの $carry の値は null ですが、reduce に第2引数を渡して初期値を指定できます。
$collection->reduce(function (int $carry, int $item) {
return $carry + $item;
}, 4);
// 10
reduce メソッドは連想配列のキーもコールバックに渡します。
$collection = collect([
'usd' => 1400,
'gbp' => 1200,
'eur' => 1000,
]);
$ratio = [
'usd' => 1,
'gbp' => 1.37,
'eur' => 1.22,
];
$collection->reduce(function (int $carry, int $value, int $key) use ($ratio) {
return $carry + ($value * $ratio[$key]);
});
// 4264
#reduceSpread() {.collection-method}
reduceSpread メソッドはコレクションを複数の値の配列に集約し、各イテレーションの結果を次のイテレーションに渡します。このメソッドは reduce に似ていますが、複数の初期値を受け取れます。
[$creditsRemaining, $batch] = Image::where('status', 'unprocessed')
->get()
->reduceSpread(function (int $creditsRemaining, Collection $batch, Image $image) {
if ($creditsRemaining >= $image->creditsRequired()) {
$batch->push($image);
$creditsRemaining -= $image->creditsRequired();
}
return [$creditsRemaining, $batch];
}, $creditsAvailable, collect());
#reject() {.collection-method}
reject メソッドは指定したクロージャでコレクションをフィルタリングします。クロージャが true を返したアイテムは結果から除外されます。
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->reject(function (int $value, int $key) {
return $value > 2;
});
$filtered->all();
// [1, 2]
reject の逆の動作は filter メソッドを参照してください。
#replace() {.collection-method}
replace メソッドは merge と同様に動作します。ただし、string キーを持つ一致する項目を上書きすることに加えて、replace は一致する数値キーを持つコレクション内の項目も上書きします:
$collection = collect(['Taylor', 'Abigail', 'James']);
$replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']);
$replaced->all();
// ['Taylor', 'Victoria', 'James', 'Finn']
#replaceRecursive() {.collection-method}
このメソッドは replace と同様ですが、配列の中も再帰的に処理して同じ置換を適用します。
$collection = collect([
'Taylor',
'Abigail',
[
'James',
'Victoria',
'Finn'
]
]);
$replaced = $collection->replaceRecursive([
'Charlie',
2 => [1 => 'King']
]);
$replaced->all();
// ['Charlie', 'Abigail', ['James', 'King', 'Finn']]
#reverse() {.collection-method}
reverse メソッドはコレクションのアイテムの順序を逆にしますが、元のキーは保持します。
$collection = collect(['a', 'b', 'c', 'd', 'e']);
$reversed = $collection->reverse();
$reversed->all();
/*
[
4 => 'e',
3 => 'd',
2 => 'c',
1 => 'b',
0 => 'a',
]
*/
#search() {.collection-method}
search メソッドは指定した値をコレクション内で検索し、見つかればキーを返します。見つからなければ false を返します。
$collection = collect([2, 4, 6, 8]);
$collection->search(4);
// 1
検索は「ゆるい」比較で行われるため、整数値の文字列は同じ値の整数と等しいとみなされます。厳密比較を使うには、第2引数に true を渡します。
collect([2, 4, 6, 8])->search('4', $strict = true);
// false
または、自分でクロージャを渡して、条件を満たす最初のアイテムを検索できます。
collect([2, 4, 6, 8])->search(function (int $item, int $key) {
return $item > 5;
});
// 2
#select() {.collection-method}
select メソッドはコレクションから指定したキーだけを選択します。SQL の SELECT 文に似ています。
$users = collect([
['name' => 'Taylor Otwell', 'role' => 'Developer', 'status' => 'active'],
['name' => 'Victoria Faith', 'role' => 'Researcher', 'status' => 'active'],
]);
$users->select(['name', 'role']);
/*
[
['name' => 'Taylor Otwell', 'role' => 'Developer'],
['name' => 'Victoria Faith', 'role' => 'Researcher'],
],
*/
#shift() {.collection-method}
shift メソッドはコレクションの最初のアイテムを削除して返します。
$collection = collect([1, 2, 3, 4, 5]);
$collection->shift();
// 1
$collection->all();
// [2, 3, 4, 5]
shift メソッドに整数を渡すと、コレクションの先頭から複数のアイテムを削除して返せます。
$collection = collect([1, 2, 3, 4, 5]);
$collection->shift(3);
// collect([1, 2, 3])
$collection->all();
// [4, 5]
#shuffle() {.collection-method}
shuffle メソッドはコレクションのアイテムをランダムにシャッフルします。
$collection = collect([1, 2, 3, 4, 5]);
$shuffled = $collection->shuffle();
$shuffled->all();
// [3, 2, 5, 1, 4] - (ランダムに生成)
#skip() {.collection-method}
skip メソッドはコレクションの先頭から指定した数の要素を除いた新しいコレクションを返します。
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
$collection = $collection->skip(4);
$collection->all();
// [5, 6, 7, 8, 9, 10]
#skipUntil() {.collection-method}
skipUntil メソッドは、指定したコールバックが true を返すまでコレクションのアイテムをスキップし、その後のアイテムを新しいコレクションインスタンスとして返します:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipUntil(function (int $item) {
return $item >= 3;
});
$subset->all();
// [3, 4]
skipUntil メソッドには単純な値を渡すこともでき、その値が見つかるまでのすべてのアイテムをスキップします:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipUntil(3);
$subset->all();
// [3, 4]
指定した値が見つからない場合やコールバックが一度も true を返さない場合、skipUntil メソッドは空のコレクションを返します。
#skipWhile() {.collection-method}
skipWhile メソッドは、指定したコールバックが true を返す間、コレクションのアイテムをスキップし、その後のアイテムを新しいコレクションとして返します:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipWhile(function (int $item) {
return $item <= 3;
});
$subset->all();
// [4]
コールバックが一度も false を返さない場合、skipWhile メソッドは空のコレクションを返します。
#slice() {.collection-method}
slice メソッドは、指定したインデックスから始まるコレクションのスライスを返します:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
$slice = $collection->slice(4);
$slice->all();
// [5, 6, 7, 8, 9, 10]
返されるスライスのサイズを制限したい場合は、メソッドの第2引数に希望のサイズを渡してください:
$slice = $collection->slice(4, 2);
$slice->all();
// [5, 6]
返されるスライスはデフォルトでキーを保持します。元のキーを保持したくない場合は、values メソッドを使って再インデックス化できます。
#sliding() {.collection-method}
sliding メソッドは、コレクションのアイテムを「スライディングウィンドウ」ビューとして表すチャンクの新しいコレクションを返します:
$collection = collect([1, 2, 3, 4, 5]);
$chunks = $collection->sliding(2);
$chunks->toArray();
// [[1, 2], [2, 3], [3, 4], [4, 5]]
これは特に eachSpread メソッドと組み合わせて便利です:
$transactions->sliding(2)->eachSpread(function (Collection $previous, Collection $current) {
$current->total = $previous->total + $current->amount;
});
// [1, 2]
$collection = collect([1, 2, 3, 4, 5]);
$chunks = $collection->sliding(3, step: 2);
$chunks->toArray();
// [[1, 2, 3], [3, 4, 5]]
#sole() {.collection-method}
sole メソッドは、指定した条件に合致する最初の要素を返しますが、その条件に合致する要素がちょうど1つだけの場合に限ります:
collect([1, 2, 3, 4])->sole(function (int $value, int $key) {
return $value === 2;
});
// 2
sole メソッドにはキーと値のペアを渡すこともでき、そのペアに合致する最初の要素を返しますが、合致する要素がちょうど1つだけの場合に限ります:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
]);
$collection->sole('product', 'Chair');
// ['product' => 'Chair', 'price' => 100]
また、引数なしで sole メソッドを呼び出すと、コレクションに要素が1つだけある場合にその要素を取得できます:
$collection = collect([
['product' => 'Desk', 'price' => 200],
]);
$collection->sole();
// ['product' => 'Desk', 'price' => 200]
sole メソッドで返すべき要素がない場合は \Illuminate\Collections\ItemNotFoundException 例外がスローされます。返すべき要素が複数ある場合は \Illuminate\Collections\MultipleItemsFoundException 例外がスローされます。
#some() {.collection-method}
contains メソッドのエイリアスです。
#sort() {.collection-method}
sort メソッドはコレクションをソートします。ソート後も元の配列キーを保持するため、以下の例では values メソッドを使ってキーを連番にリセットしています:
$collection = collect([5, 3, 1, 2, 4]);
$sorted = $collection->sort();
$sorted->values()->all();
// [1, 2, 3, 4, 5]
より高度なソートが必要な場合は、独自のアルゴリズムを用いたコールバックをsortに渡すことができます。コレクションのsortメソッドが内部で利用しているのは uasort なので、該当するPHPドキュメントを参照してください。
ネストされた配列やオブジェクトのコレクションをソートする場合は、sortBy と sortByDesc メソッドを参照してください。
#sortBy() {.collection-method}
sortBy メソッドは指定したキーでコレクションをソートします。ソート後も元の配列キーを保持するため、以下の例では values メソッドを使ってキーを連番にリセットしています:
$collection = collect([
['name' => 'Desk', 'price' => 200],
['name' => 'Chair', 'price' => 100],
['name' => 'Bookcase', 'price' => 150],
]);
$sorted = $collection->sortBy('price');
$sorted->values()->all();
/*
[
['name' => 'Chair', 'price' => 100],
['name' => 'Bookcase', 'price' => 150],
['name' => 'Desk', 'price' => 200],
]
*/
sortBy メソッドは第2引数に ソートフラグ を受け取れます:
$collection = collect([
['title' => 'Item 1'],
['title' => 'Item 12'],
['title' => 'Item 3'],
]);
$sorted = $collection->sortBy('title', SORT_NATURAL);
$sorted->values()->all();
/*
[
['title' => 'Item 1'],
['title' => 'Item 3'],
['title' => 'Item 12'],
]
*/
または、独自のクロージャを渡してコレクションの値のソート方法を定義できます:
$collection = collect([
['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
['name' => 'Chair', 'colors' => ['Black']],
['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]);
$sorted = $collection->sortBy(function (array $product, int $key) {
return count($product['colors']);
});
$sorted->values()->all();
/*
[
['name' => 'Chair', 'colors' => ['Black']],
['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]
*/
複数の属性でソートしたい場合は、ソートしたい属性の配列を渡せます:
$collection = collect([
['name' => 'Taylor Otwell', 'age' => 34],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Abigail Otwell', 'age' => 32],
]);
$sorted = $collection->sortBy(['name', 'age']);
$sorted->values()->all();
/*
[
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Abigail Otwell', 'age' => 32],
['name' => 'Taylor Otwell', 'age' => 34],
['name' => 'Taylor Otwell', 'age' => 36],
]
*/
複数の属性と方向でソートする場合は、sortBy メソッドにソート操作の配列を渡せます。各操作はソートしたい属性と方向を含む配列です:
$collection = collect([
['name' => 'Taylor Otwell', 'age' => 34],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Abigail Otwell', 'age' => 32],
]);
$sorted = $collection->sortBy([
['name', 'asc'],
['age', 'desc'],
]);
$sorted->values()->all();
/*
[
['name' => 'Abigail Otwell', 'age' => 32],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Taylor Otwell', 'age' => 34],
]
*/
複数属性のソートで、各操作を定義するクロージャを渡すこともできます:
$collection = collect([
['name' => 'Taylor Otwell', 'age' => 34],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Abigail Otwell', 'age' => 32],
]);
$sorted = $collection->sortBy([
fn (array $a, array $b) => $a['name'] <=> $b['name'],
fn (array $a, array $b) => $b['age'] <=> $a['age'],
]);
$sorted->values()->all();
/*
[
['name' => 'Abigail Otwell', 'age' => 32],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Taylor Otwell', 'age' => 34],
]
*/
#sortByDesc() {.collection-method}
このメソッドは sortBy と同じシグネチャですが、逆順でコレクションをソートします。
#sortDesc() {.collection-method}
このメソッドは sort と逆の順序でコレクションをソートします:
$collection = collect([5, 3, 1, 2, 4]);
$sorted = $collection->sortDesc();
$sorted->values()->all();
// [5, 4, 3, 2, 1]
sort と違い、sortDesc にはクロージャを渡せません。代わりに sort メソッドを使い、比較を反転させてください。
#sortKeys() {.collection-method}
sortKeys メソッドは、基になる連想配列のキーでコレクションをソートします:
$collection = collect([
'id' => 22345,
'first' => 'John',
'last' => 'Doe',
]);
$sorted = $collection->sortKeys();
$sorted->all();
/*
[
'first' => 'John',
'id' => 22345,
'last' => 'Doe',
]
*/
#sortKeysDesc() {.collection-method}
このメソッドは sortKeys と同じシグネチャですが、逆順でコレクションをソートします。
#sortKeysUsing() {.collection-method}
sortKeysUsing メソッドは、コールバックを使って基になる連想配列のキーでコレクションをソートします:
$collection = collect([
'ID' => 22345,
'first' => 'John',
'last' => 'Doe',
]);
$sorted = $collection->sortKeysUsing('strnatcasecmp');
$sorted->all();
/*
[
'first' => 'John',
'ID' => 22345,
'last' => 'Doe',
]
*/
コールバックは、0未満、0、0より大きい整数を返す比較関数である必要があります。詳細は PHP の uksort ドキュメントを参照してください。これは sortKeysUsing が内部で利用している関数です。
#splice() {.collection-method}
splice メソッドは、指定したインデックスから始まるアイテムのスライスを削除して返します:
$collection = collect([1, 2, 3, 4, 5]);
$chunk = $collection->splice(2);
$chunk->all();
// [3, 4, 5]
$collection->all();
// [1, 2]
第2引数にサイズを渡して、結果のコレクションのサイズを制限できます:
$collection = collect([1, 2, 3, 4, 5]);
$chunk = $collection->splice(2, 1);
$chunk->all();
// [3]
$collection->all();
// [1, 2, 4, 5]
さらに、第3引数に新しいアイテムの配列を渡して、削除したアイテムを置き換えられます:
$collection = collect([1, 2, 3, 4, 5]);
$chunk = $collection->splice(2, 1, [10, 11]);
$chunk->all();
// [3]
$collection->all();
// [1, 2, 10, 11, 4, 5]
#split() {.collection-method}
split メソッドは、コレクションを指定した数のグループに分割します:
$collection = collect([1, 2, 3, 4, 5]);
$groups = $collection->split(3);
$groups->all();
// [[1, 2], [3, 4], [5]]
#splitIn() {.collection-method}
splitIn メソッドは、コレクションを指定した数のグループに分割します。終端以外のグループは完全に埋められ、残りは最後のグループに割り当てられます。
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
$groups = $collection->splitIn(3);
$groups->all();
// [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
#sum() {.collection-method}
sum メソッドは、コレクション内のすべてのアイテムの合計を返します。
collect([1, 2, 3, 4, 5])->sum();
// 15
コレクションにネストされた配列やオブジェクトが含まれる場合は、合計する値を決定するためのキーを渡す必要があります。
$collection = collect([
['name' => 'JavaScript: The Good Parts', 'pages' => 176],
['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096],
]);
$collection->sum('pages');
// 1272
さらに、コレクションのどの値を合計するかを決定するために、独自のクロージャを渡すこともできます。
$collection = collect([
['name' => 'Chair', 'colors' => ['Black']],
['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]);
$collection->sum(function (array $product) {
return count($product['colors']);
});
// 6
#take() {.collection-method}
take メソッドは、指定した数のアイテムを含む新しいコレクションを返します。
$collection = collect([0, 1, 2, 3, 4, 5]);
$chunk = $collection->take(3);
$chunk->all();
// [0, 1, 2]
負の整数を渡すと、コレクションの末尾から指定した数のアイテムを取得できます。
$collection = collect([0, 1, 2, 3, 4, 5]);
$chunk = $collection->take(-2);
$chunk->all();
// [4, 5]
#takeUntil() {.collection-method}
takeUntil メソッドは、指定したコールバックが true を返すまでコレクションのアイテムを返します。
$collection = collect([1, 2, 3, 4]);
$subset = $collection->takeUntil(function (int $item) {
return $item >= 3;
});
$subset->all();
// [1, 2]
単純な値を takeUntil メソッドに渡すこともでき、その値が見つかるまでのアイテムを取得します。
$collection = collect([1, 2, 3, 4]);
$subset = $collection->takeUntil(3);
$subset->all();
// [1, 2]
指定した値が見つからない場合やコールバックが一度も true を返さない場合、takeUntil メソッドはコレクション内のすべてのアイテムを返します。
#takeWhile() {.collection-method}
takeWhile メソッドは、指定したコールバックが false を返すまでコレクションのアイテムを返します。
$collection = collect([1, 2, 3, 4]);
$subset = $collection->takeWhile(function (int $item) {
return $item < 3;
});
$subset->all();
// [1, 2]
コールバックが一度も false を返さない場合、takeWhile メソッドはコレクション内のすべてのアイテムを返します。
#tap() {.collection-method}
tap メソッドはコレクションを指定したコールバックに渡し、特定の時点でコレクションに対して "tap" してアイテムに対して何らかの処理を行えますが、コレクション自体には影響を与えません。コレクションはその後 tap メソッドによって返されます:
collect([2, 4, 3, 1, 5])
->sort()
->tap(function (Collection $collection) {
Log::debug('Values after sorting', $collection->values()->all());
})
->shift();
// 1
#times() {.collection-method}
静的な times メソッドは、指定した回数だけクロージャを呼び出して新しいコレクションを作成します。
$collection = Collection::times(10, function (int $number) {
return $number * 9;
});
$collection->all();
// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
#toArray() {.collection-method}
toArray メソッドはコレクションをプレーンな PHP の array に変換します。コレクションの値が Eloquent のモデルである場合、モデルも配列に変換されます:
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toArray();
/*
[
['name' => 'Desk', 'price' => 200],
]
*/
toArray はコレクション内の Arrayable インスタンスのネストされたオブジェクトも配列に変換します。コレクションの元の配列を取得したい場合は、代わりに all メソッドを使ってください。
#toJson() {.collection-method}
toJson メソッドはコレクションを JSON シリアライズされた文字列に変換します。
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toJson();
// '{"name":"Desk", "price":200}'
#transform() {.collection-method}
transform メソッドはコレクションの各アイテムに対して指定したコールバックを呼び出し、コールバックの返り値でアイテムを置き換えます。
$collection = collect([1, 2, 3, 4, 5]);
$collection->transform(function (int $item, int $key) {
return $item * 2;
});
$collection->all();
// [2, 4, 6, 8, 10]
他の多くのコレクションメソッドと異なり、transform はコレクション自体を変更します。新しいコレクションを作成したい場合は、map メソッドを使ってください。
#undot() {.collection-method}
undot メソッドは、ドット記法を使った一次元のコレクションを多次元のコレクションに展開します。
$person = collect([
'name.first_name' => 'Marie',
'name.last_name' => 'Valentine',
'address.line_1' => '2992 Eagle Drive',
'address.line_2' => '',
'address.suburb' => 'Detroit',
'address.state' => 'MI',
'address.postcode' => '48219'
]);
$person = $person->undot();
$person->toArray();
/*
[
"name" => [
"first_name" => "Marie",
"last_name" => "Valentine",
],
"address" => [
"line_1" => "2992 Eagle Drive",
"line_2" => "",
"suburb" => "Detroit",
"state" => "MI",
"postcode" => "48219",
],
]
*/
#union() {.collection-method}
union メソッドは指定した配列をコレクションに追加します。指定した配列に元のコレクションに存在するキーが含まれている場合は、元のコレクションの値が優先されます。
$collection = collect([1 => ['a'], 2 => ['b']]);
$union = $collection->union([3 => ['c'], 1 => ['d']]);
$union->all();
// [1 => ['a'], 2 => ['b'], 3 => ['c']]
#unique() {.collection-method}
unique メソッドはコレクション内のユニークなアイテムを返します。返されるコレクションは元の配列キーを保持するため、以下の例では values メソッドを使って連続したインデックスにリセットしています。
$collection = collect([1, 1, 2, 2, 3, 4, 2]);
$unique = $collection->unique();
$unique->values()->all();
// [1, 2, 3, 4]
ネストされた配列やオブジェクトを扱う場合、ユニーク判定に使うキーを指定できます。
$collection = collect([
['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'],
['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],
['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],
]);
$unique = $collection->unique('brand');
$unique->values()->all();
/*
[
['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
]
*/
最後に、unique メソッドには独自のクロージャを渡して、どの値でユニーク判定するかを指定できます。
$unique = $collection->unique(function (array $item) {
return $item['brand'].$item['type'];
});
$unique->values()->all();
/*
[
['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],
['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],
]
*/
unique メソッドはアイテムの値を比較する際に「ゆるい」比較を使います。つまり、整数値の文字列は同じ値の整数と等しいとみなされます。厳密な比較を使いたい場合は uniqueStrict メソッドを使ってください。
このメソッドの挙動は Eloquent Collections 使用時に変更されます。
#uniqueStrict() {.collection-method}
このメソッドは unique と同じシグネチャですが、すべての値を「厳密」比較で判定します。
#unless() {.collection-method}
unless メソッドは、最初の引数が true と評価されない限り、指定したコールバックを実行します。
$collection = collect([1, 2, 3]);
$collection->unless(true, function (Collection $collection) {
return $collection->push(4);
});
$collection->unless(false, function (Collection $collection) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 5]
unless メソッドには2番目のコールバックを渡すことができます。unless メソッドに渡された最初の引数がtrueと評価される場合、2番目のコールバックが実行されます:
$collection = collect([1, 2, 3]);
$collection->unless(true, function (Collection $collection) {
return $collection->push(4);
}, function (Collection $collection) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 5]
unless の逆の動作は when メソッドを参照してください。
#unlessEmpty() {.collection-method}
whenNotEmpty メソッドのエイリアスです。
#unlessNotEmpty() {.collection-method}
whenEmpty メソッドのエイリアスです。
#unwrap() {.collection-method}
静的な unwrap メソッドは、渡された値がコレクションの場合はその中身のアイテムを返します。
Collection::unwrap(collect('John Doe'));
// ['John Doe']
Collection::unwrap(['John Doe']);
// ['John Doe']
Collection::unwrap('John Doe');
// 'John Doe'
#value() {.collection-method}
value メソッドは、コレクションの最初の要素から指定した値を取得します。
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Speaker', 'price' => 400],
]);
$value = $collection->value('price');
// 200
#values() {.collection-method}
values メソッドは、キーを連続した整数にリセットした新しいコレクションを返します。
$collection = collect([
10 => ['product' => 'Desk', 'price' => 200],
11 => ['product' => 'Desk', 'price' => 200],
]);
$values = $collection->values();
$values->all();
/*
[
0 => ['product' => 'Desk', 'price' => 200],
1 => ['product' => 'Desk', 'price' => 200],
]
*/
#when() {.collection-method}
The when メソッドは、メソッドに渡された最初の引数が true と評価されると指定したコールバックを実行します。when メソッドに渡されたコレクションのインスタンスと最初の引数はクロージャに渡されます:
$collection = collect([1, 2, 3]);
$collection->when(true, function (Collection $collection, int $value) {
return $collection->push(4);
});
$collection->when(false, function (Collection $collection, int $value) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 4]
二番目のコールバックを when メソッドに渡すことができます。when メソッドに渡された最初の引数が false と評価される場合、二番目のコールバックが実行されます:
$collection = collect([1, 2, 3]);
$collection->when(false, function (Collection $collection, int $value) {
return $collection->push(4);
}, function (Collection $collection) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 5]
when の逆の動作については、unless メソッドを参照してください。
#whenEmpty() {.collection-method}
whenEmpty メソッドは、コレクションが空の場合に指定したコールバックを実行します:
$collection = collect(['Michael', 'Tom']);
$collection->whenEmpty(function (Collection $collection) {
return $collection->push('Adam');
});
$collection->all();
// ['Michael', 'Tom']
$collection = collect();
$collection->whenEmpty(function (Collection $collection) {
return $collection->push('Adam');
});
$collection->all();
// ['Adam']
whenEmpty メソッドには、コレクションが空でない場合に実行される第2のクロージャを渡すこともできます:
$collection = collect(['Michael', 'Tom']);
$collection->whenEmpty(function (Collection $collection) {
return $collection->push('Adam');
}, function (Collection $collection) {
return $collection->push('Taylor');
});
$collection->all();
// ['Michael', 'Tom', 'Taylor']
whenEmpty の逆の動作については、whenNotEmpty メソッドを参照してください。
#whenNotEmpty() {.collection-method}
whenNotEmpty メソッドは、コレクションが空でない場合に指定したコールバックを実行します:
$collection = collect(['michael', 'tom']);
$collection->whenNotEmpty(function (Collection $collection) {
return $collection->push('adam');
});
$collection->all();
// ['michael', 'tom', 'adam']
$collection = collect();
$collection->whenNotEmpty(function (Collection $collection) {
return $collection->push('adam');
});
$collection->all();
// []
whenNotEmpty メソッドには、コレクションが空の場合に実行される第2のクロージャを渡すこともできます:
$collection = collect();
$collection->whenNotEmpty(function (Collection $collection) {
return $collection->push('adam');
}, function (Collection $collection) {
return $collection->push('taylor');
});
$collection->all();
// ['taylor']
whenNotEmpty の逆の動作については、whenEmpty メソッドを参照してください。
#where() {.collection-method}
where メソッドは、指定したキーと値のペアでコレクションをフィルタリングします:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Door', 'price' => 100],
]);
$filtered = $collection->where('price', 100);
$filtered->all();
/*
[
['product' => 'Chair', 'price' => 100],
['product' => 'Door', 'price' => 100],
]
*/
where メソッドは値の比較に「ゆるい」比較を使います。つまり、整数値の文字列は同じ値の整数と等しいとみなされます。厳密な比較でフィルタリングしたい場合は、whereStrict メソッドを使ってください。
オプションで、第2引数に比較演算子を渡せます。サポートされている演算子は、'===', '!==', '!=', '==', '=', '<>', '>', '<', '>=', '<=' です:
$collection = collect([
['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'],
['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'],
['name' => 'Sue', 'deleted_at' => null],
]);
$filtered = $collection->where('deleted_at', '!=', null);
$filtered->all();
/*
[
['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'],
['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'],
]
*/
#whereStrict() {.collection-method}
このメソッドはwhereメソッドと同じシグネチャですが、すべての値を「厳密」比較で評価します。
#whereBetween() {.collection-method}
whereBetween メソッドは、指定した値がある範囲内にあるかどうかでコレクションをフィルタリングします:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 80],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Pencil', 'price' => 30],
['product' => 'Door', 'price' => 100],
]);
$filtered = $collection->whereBetween('price', [100, 200]);
$filtered->all();
/*
[
['product' => 'Desk', 'price' => 200],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Door', 'price' => 100],
]
*/
#whereIn() {.collection-method}
whereIn メソッドは、指定した配列に含まれていない値を持つ要素をコレクションから除外します:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Door', 'price' => 100],
]);
$filtered = $collection->whereIn('price', [150, 200]);
$filtered->all();
/*
[
['product' => 'Desk', 'price' => 200],
['product' => 'Bookcase', 'price' => 150],
]
*/
whereIn メソッドは値の比較に「ゆるい」比較を使います。つまり、整数値の文字列は同じ値の整数と等しいとみなされます。厳密な比較でフィルタリングしたい場合は、whereInStrict メソッドを使ってください。
#whereInStrict() {.collection-method}
このメソッドはwhereInメソッドと同じシグネチャですが、すべての値を「厳密」比較で評価します。
#whereInstanceOf() {.collection-method}
whereInstanceOf メソッドは、指定したクラスのインスタンスかどうかでコレクションをフィルタリングします:
use App\Models\User;
use App\Models\Post;
$collection = collect([
new User,
new User,
new Post,
]);
$filtered = $collection->whereInstanceOf(User::class);
$filtered->all();
// [App\Models\User, App\Models\User]
#whereNotBetween() {.collection-method}
whereNotBetween メソッドは、指定した値がある範囲外にあるかどうかでコレクションをフィルタリングします:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 80],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Pencil', 'price' => 30],
['product' => 'Door', 'price' => 100],
]);
$filtered = $collection->whereNotBetween('price', [100, 200]);
$filtered->all();
/*
[
['product' => 'Chair', 'price' => 80],
['product' => 'Pencil', 'price' => 30],
]
*/
#whereNotIn() {.collection-method}
whereNotIn メソッドは、指定した配列に含まれている値を持つ要素をコレクションから除外します:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Door', 'price' => 100],
]);
$filtered = $collection->whereNotIn('price', [150, 200]);
$filtered->all();
/*
[
['product' => 'Chair', 'price' => 100],
['product' => 'Door', 'price' => 100],
]
*/
whereNotIn メソッドは値の比較に「ゆるい」比較を使います。つまり、整数値の文字列は同じ値の整数と等しいとみなされます。厳密な比較でフィルタリングしたい場合は、whereNotInStrict メソッドを使ってください。
#whereNotInStrict() {.collection-method}
このメソッドはwhereNotInメソッドと同じシグネチャですが、すべての値を「厳密」比較で評価します。
#whereNotNull() {.collection-method}
whereNotNull メソッドは、指定したキーの値が null でないアイテムを返します:
$collection = collect([
['name' => 'Desk'],
['name' => null],
['name' => 'Bookcase'],
]);
$filtered = $collection->whereNotNull('name');
$filtered->all();
/*
[
['name' => 'Desk'],
['name' => 'Bookcase'],
]
*/
#whereNull() {.collection-method}
whereNull メソッドは、指定したキーの値が null のアイテムを返します:
$collection = collect([
['name' => 'Desk'],
['name' => null],
['name' => 'Bookcase'],
]);
$filtered = $collection->whereNull('name');
$filtered->all();
/*
[
['name' => null],
]
*/
#wrap() {.collection-method}
静的な wrap メソッドは、渡された値をコレクションにラップします(必要に応じて):
use Illuminate\Support\Collection;
$collection = Collection::wrap('John Doe');
$collection->all();
// ['John Doe']
$collection = Collection::wrap(['John Doe']);
$collection->all();
// ['John Doe']
$collection = Collection::wrap(collect('John Doe'));
$collection->all();
// ['John Doe']
#zip() {.collection-method}
zip メソッドは、元のコレクションの値と渡された配列の値を対応するインデックスで結合します:
$collection = collect(['Chair', 'Desk']);
$zipped = $collection->zip([100, 200]);
$zipped->all();
// [['Chair', 100], ['Desk', 200]]
#高階メッセージ
コレクションは「ハイアーオーダーメッセージ」もサポートしており、これはコレクションに対する一般的な操作を簡潔に行うショートカットです。ハイアーオーダーメッセージを提供するコレクションメソッドは、average、avg、contains、each、every、filter、first、flatMap、groupBy、keyBy、map、max、min、partition、reject、skipUntil、skipWhile、some、sortBy、sortByDesc、sum、takeUntil、takeWhile、unique です。
各ハイアーオーダーメッセージは、コレクションインスタンスの動的プロパティとしてアクセスできます。例えば、each ハイアーオーダーメッセージを使って、コレクション内の各オブジェクトのメソッドを呼び出せます:
use App\Models\User;
$users = User::where('votes', '>', 500)->get();
$users->each->markAsVip();
同様に、sum ハイアーオーダーメッセージを使って、ユーザーコレクションの "votes" の合計を取得できます:
$users = User::where('group', 'Development')->get();
return $users->sum->votes;
#遅延コレクション
#Introduction
Laravel の Lazy Collections について学ぶ前に、PHPのジェネレーターを理解しておくことをおすすめします。
強力な Collection クラスを補完するために、LazyCollection クラスは PHP の ジェネレーター を活用し、大量のデータセットを扱いながらメモリ使用量を抑えられます。
例えば、マルチギガバイトのログファイルを処理しつつ、Laravel のコレクションメソッドを使ってログを解析したい場合、ファイル全体を一度にメモリに読み込むのではなく、Lazy Collections を使って一度にファイルの一部だけをメモリに保持できます:
use App\Models\LogEntry;
use Illuminate\Support\LazyCollection;
LazyCollection::make(function () {
$handle = fopen('log.txt', 'r');
while (($line = fgets($handle)) !== false) {
yield $line;
}
})->chunk(4)->map(function (array $lines) {
return LogEntry::fromLines($lines);
})->each(function (LogEntry $logEntry) {
// ログエントリを処理します...
});
例えば、10,000件のEloquentモデルを繰り返し処理する必要があるとします。従来のLaravelコレクションを使う場合、10,000件すべてのEloquentモデルを一度にメモリに読み込む必要があります。
use App\Models\User;
$users = User::all()->filter(function (User $user) {
return $user->id > 500;
});
しかし、クエリビルダーのcursorメソッドはLazyCollectionインスタンスを返します。これにより、データベースに対しては単一のクエリだけを実行しつつ、メモリには一度に1つのEloquentモデルだけを保持できます。この例では、filterのコールバックは実際に各ユーザーを個別に繰り返すまで実行されないため、メモリ使用量を大幅に削減できます。
use App\Models\User;
$users = User::cursor()->filter(function (User $user) {
return $user->id > 500;
});
foreach ($users as $user) {
echo $user->id;
}
#Lazy Collectionの作成
Lazy Collectionインスタンスを作成するには、PHPのジェネレーター関数をコレクションのmakeメソッドに渡します。
use Illuminate\Support\LazyCollection;
LazyCollection::make(function () {
$handle = fopen('log.txt', 'r');
while (($line = fgets($handle)) !== false) {
yield $line;
}
});
#Enumerable契約
Collectionクラスで利用可能なほとんどのメソッドは、LazyCollectionクラスでも利用できます。これら両クラスはIlluminate\Support\Enumerable契約を実装しており、以下のメソッドを定義しています。
all average avg chunk chunkWhile collapse collect combine concat contains containsStrict count countBy crossJoin dd diff diffAssoc diffKeys dump duplicates duplicatesStrict each eachSpread every except filter first firstOrFail firstWhere flatMap flatten flip forPage get groupBy has implode intersect intersectAssoc intersectByKeys isEmpty isNotEmpty join keyBy keys last macro make map mapInto mapSpread mapToGroups mapWithKeys max median merge mergeRecursive min mode nth only pad partition pipe pluck random reduce reject replace replaceRecursive reverse search shuffle skip slice sole some sort sortBy sortByDesc sortKeys sortKeysDesc split sum take tap times toArray toJson union unique uniqueStrict unless unlessEmpty unlessNotEmpty unwrap values when whenEmpty whenNotEmpty where whereStrict whereBetween whereIn whereInStrict whereInstanceOf whereNotBetween whereNotIn whereNotInStrict wrap zip
コレクションを変更するメソッド(shift、pop、prependなど)はLazyCollectionクラスでは利用できません。
#Lazy Collectionのメソッド
Enumerable契約で定義されたメソッドに加え、LazyCollectionクラスには以下のメソッドがあります。
#takeUntilTimeout() {.collection-method}
takeUntilTimeoutメソッドは、指定した時間まで値を列挙し続ける新しいLazy Collectionを返します。その時間を過ぎると列挙を停止します。
$lazyCollection = LazyCollection::times(INF)
->takeUntilTimeout(now()->addMinute());
$lazyCollection->each(function (int $number) {
dump($number);
sleep(1);
});
// 1
// 2
// ...
// 58
// 59
このメソッドの使い方を説明するために、カーソルを使ってデータベースから請求書を送信するアプリケーションを想像してください。15分ごとに実行され、最大14分間だけ請求書を処理するスケジュールタスクを定義できます。
use App\Models\Invoice;
use Illuminate\Support\Carbon;
Invoice::pending()->cursor()
->takeUntilTimeout(
Carbon::createFromTimestamp(LARAVEL_START)->add(14, 'minutes')
)
->each(fn (Invoice $invoice) => $invoice->submit());
#tapEach() {.collection-method}
eachメソッドはコレクション内の各アイテムに対してすぐにコールバックを呼び出しますが、tapEachメソッドはアイテムが1つずつ取り出される際にのみコールバックを呼び出します。
// これまで何もダンプされていません...
$lazyCollection = LazyCollection::times(INF)->tapEach(function (int $value) {
dump($value);
});
// 3つのアイテムがダンプされます...
$array = $lazyCollection->take(3)->all();
// 1
// 2
// 3
#remember() {.collection-method}
rememberメソッドは、すでに列挙された値を記憶し、次回以降の列挙で再取得しない新しいLazy Collectionを返します。
// まだクエリは実行されていません...
$users = User::cursor()->remember();
// クエリが実行されます...
// 最初の5人のユーザーがデータベースから取得されます... $users->take(5)->all();
// 最初の5人はコレクションのキャッシュから取得されます...
// 残りはデータベースから取得されます... $users->take(20)->all();