イントロダクション
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]);
Note: Eloquentクエリの結果は、常に
Collection
インスタンスを返します。
コレクションの拡張
コレクションは「マクロ化可能」であり、実行時にCollection
クラスへメソッドを追加できます。Illuminate\Support\Collection
クラスのmacro
メソッドは、マクロが呼び出されたときに実行するクロージャを引数に取ります。マクロクロージャは、コレクションクラスの実際のメソッドであるかのように、$this
を介してコレクションの他のメソッドにアクセスできます。たとえば、次のコードは、toUpper
メソッドをCollection
クラスに追加しています。
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()
all
メソッドはコレクションの元の配列表現を返します。
collect([1, 2, 3])->all();
// [1, 2, 3]
average()
avg
メソッドのエイリアスです。
avg()
avg
メソッドは、指定したキーの平均値を返します。
$average = collect([
['foo' => 10],
['foo' => 10],
['foo' => 20],
['foo' => 40]
])->avg('foo');
// 20
$average = collect([1, 1, 2, 4])->avg();
// 2
chunk()
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()
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()
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()
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]
Note:
collect
メソッドはEnumerable
のインスタンスがあり、それをレイジーコレクションでなくする必要がある場合、とくに便利です。collect()
はEnumerable
契約の一部であり、Collection
インスタンスを取得するため安全に使用できます。
combine()
combine
メソッドは、コレクションの値をキーとして、他の配列かコレクションの値を結合します。
$collection = collect(['name', 'age']);
$combined = $collection->combine(['George', 29]);
$combined->all();
// ['name' => 'George', 'age' => 29]
concat()
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()
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()
containsOneItem
メソッドは、コレクションに項目が1つ含まれているかを判断します。
collect([])->containsOneItem();
// false
collect(['1'])->containsOneItem();
// true
collect(['1', '2'])->containsOneItem();
// false
containsStrict()
このメソッドは、contains
メソッドと使用方法は同じです。しかし、「厳密」な値の比較を行います。
Note: Eloquentコレクションの使用時は、このメソッドの振る舞いが変わります。
count()
count
メソッドはコレクションのアイテム数を返します。
$collection = collect([1, 2, 3, 4]);
$collection->count();
// 4
countBy()
countBy
メソッドは、コレクション内の値の出現をカウントします。このメソッドはデフォルトで、コレクション内の要素の特定の「タイプ」をカウントできるよう、すべての要素の出現をカウントします。
$collection = collect([1, 2, 2, 2, 3]);
$counted = $collection->countBy();
$counted->all();
// [1 => 1, 2 => 3, 3 => 1]
countBy
メソッドにクロージャを渡して、すべてのアイテムをカスタム値でカウントします。
$collection = collect(['alice@gmail.com', 'bob@yahoo.com', 'carlos@gmail.com']);
$counted = $collection->countBy(function (string $email) {
return substr(strrchr($email, "@"), 1);
});
$counted->all();
// ['gmail.com' => 2, 'yahoo.com' => 1]
crossJoin()
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()
dd
メソッドはコレクションアイテムをダンプし、スクリプトの実行を停止します。
$collection = collect(['John Doe', 'Jane Doe']);
$collection->dd();
/*
Collection {
#items: array:2 [
0 => "John Doe"
1 => "Jane Doe"
]
}
*/
スクリプトの実行を止めたくない場合は、dump
メソッドを代わりに使用してください。
diff()
diff
メソッドはコレクションと、他のコレクションか一次元「配列」を値にもとづき比較します。このメソッドは指定されたコレクションに存在しない、オリジナルのコレクションの値を返します。
$collection = collect([1, 2, 3, 4, 5]);
$diff = $collection->diff([2, 4, 6, 8]);
$diff->all();
// [1, 3, 5]
Note: Eloquentコレクションの使用時は、このメソッドの振る舞いは変わります。
diffAssoc()
diffAssoc
メソッドはコレクションと、他のコレクションかキー/値形式のPHP配列を比較します。このメソッドは指定したコレクションに含まれない、オリジナルコレクション中のキー/値ペアを返します。
$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()
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より小さい、等しい、大きい整数を返す比較関数でなければなりません。詳細は、PHPドキュメントのarray_diff_uassoc
を参照してください。このPHP関数をdiffAssocUsing
メソッドは内部で使用しています。
diffKeys()
diffKeys
メソッドはコレクションと、他のコレクションか一次元「配列」をキーで比較します。このメソッドは指定したコレクションに存在しない、オリジナルコレクション中のキー/値ペアを返します。
$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()
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()
dot
メソッドは、多次元コレクションを、次元を示す「ドット」記法を用いた、1次元のコレクションにします。
$collection = collect(['products' => ['desk' => ['price' => 100]]]);
$flattened = $collection->dot();
$flattened->all();
// ['products.desk.price' => 100]
dump()
dump
メソッドはコレクションアイテムをダンプします。
$collection = collect(['John Doe', 'Jane Doe']);
$collection->dump();
/*
Collection {
#items: array:2 [
0 => "John Doe"
1 => "Jane Doe"
]
}
*/
コレクションをダンプした後にスクリプトを停止したい場合は、代わりにdd
メソッドを使用してください。
duplicates()
duplicates
メソッドはコレクション中の重複値を返します。
$collection = collect(['a', 'b', 'a', 'c', 'b']);
$collection->duplicates();
// [2 => 'a', 4 => 'b']
コレクションが配列やオブジェクトを含む場合は、値の重複を調べたい属性のキーを渡せます。
$employees = collect([
['email' => 'abigail@example.com', 'position' => 'Developer'],
['email' => 'james@example.com', 'position' => 'Designer'],
['email' => 'victoria@example.com', 'position' => 'Developer'],
]);
$employees->duplicates('position');
// [2 => 'Developer']
duplicatesStrict()
このメソッドの使い方はduplicates
メソッドと同じですが、すべての値に「厳密な」比較が行われます。
each()
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()
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()
ensure
メソッドを使うと、コレクションのすべての要素が指定型であることを確認するために使います。不一致の場合はUnexpectedValueException
を投げます。
return $collection->ensure(User::class);
string
、int
、float
、bool
、array
などのプリミティブ型も指定できます。
return $collection->ensure('int');
Warning!!
ensure
メソッドは、後から異なる型の要素がコレクションへ追加されないことを保証しません。
every()
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()
except
メソッドは、キーにより指定したアイテム以外の全コレクション要素を返します。
$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]);
$filtered = $collection->except(['price', 'discount']);
$filtered->all();
// ['product_id' => 1]
except
の正反対の機能は、onlyメソッドです。
Note: Eloquentコレクションの使用時は、このメソッドの振る舞いは変わります。
filter()
filter
メソッドは指定したコールバックでコレクションをフィルタリングします。テストでtrueを返したアイテムだけが残ります。
$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()
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()
firstOrFail
メソッドは、結果が見つからない場合にIlluminate\Support\ItemNotFoundException
例外を投げる以外、first
メソッドと同じです。
collect([1, 2, 3, 4])->firstOrFail(function (int $value, int $key) {
return $value > 5;
});
// ItemNotFoundExceptionを投げる
また、引数なしでfirstOrFail
メソッドを呼び出すと、コレクション内の最初の要素を取得できます。コレクションが空の場合、Illuminate\Support\ItemNotFoundException
例外を投げます。
collect([])->firstOrFail();
// ItemNotFoundExceptionを投げる
firstWhere()
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
メソッドへ一つの引数を渡せます。その場合、firstWhere
メソッドは、指定したアイテムキー値が「真と見なせる」最初のアイテムを返します。
$collection->firstWhere('age');
// ['name' => 'Linda', 'age' => 14]
flatMap()
flatMap
メソッドはコレクションを反復処理し、各値を指定したクロージャに渡します。クロージャはアイテムを自由に変更して返却できるため、変更されたアイテムの新しいコレクションを形成します。それから、一次配列へフラット化します。
$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()
flatten
メソッドは多次元コレクションを一次元化します。
$collection = collect([
'name' => 'taylor',
'languages' => [
'php', 'javascript'
]
]);
$flattened = $collection->flatten();
$flattened->all();
// ['taylor', 'php', 'javascript'];
必要に応じて、flatten
メソッドに「depth」引数を渡すことができます。
$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
を呼び出すと、ネストした配列もフラットにし、['iPhone6S'、'Apple'、'GalaxyS7'、'Samsung']
になります。深さを指定すると、ネストした配列をフラット化するレベルの数を指定できます。
flip()
flip
メソッドはコレクションのキーと対応する値を入れ替えます。
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);
$flipped = $collection->flip();
$flipped->all();
// ['taylor' => 'name', 'laravel' => 'framework']
forget()
forget
メソッドはキーによりコレクションのアイテムを削除します。
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);
$collection->forget('name');
$collection->all();
// ['framework' => 'laravel']
Warning!! 他のコレクションメソッドとは異なり、
forget
は更新された新しいコレクションを返しません。呼び出しもとのコレクションを更新します。
forPage()
forPage
メソッドは指定されたページ番号を表すアイテムで構成された新しいコレクションを返します。このメソッドは最初の引数にページ番号、2つ目の引数としてページあたりのアイテム数を受け取ります。
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);
$chunk = $collection->forPage(2, 3);
$chunk->all();
// [4, 5, 6]
get()
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 'taylor@example.com';
});
// taylor@example.com
groupBy()
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()
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()
hasAny
メソッドは、指定したキーのいずれが、コレクション内に存在するか判定します。
$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]);
$collection->hasAny(['product', 'price']);
// true
$collection->hasAny(['name', 'price']);
// false
implode()
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()
intersect
メソッドは、指定した「配列」かコレクションに存在していない値をオリジナルコレクションから取り除きます。結果のコレクションには、オリジナルコレクションのキーがリストされます。
$collection = collect(['Desk', 'Sofa', 'Chair']);
$intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']);
$intersect->all();
// [0 => 'Desk', 2 => 'Chair']
Note: Eloquentコレクションの使用時は、このメソッドの振る舞いは変わります。
intersectAssoc()
intersectAssoc
メソッドは、元のコレクションと別のコレクションまたは配列(array
)を比較し、指定したコレクションの全てに存在するキーと値のペアを返します。
$collection = collect([
'color' => 'red',
'size' => 'M',
'material' => 'cotton'
]);
$intersect = $collection->intersectAssoc([
'color' => 'blue',
'size' => 'M',
'material' => 'polyester'
]);
$intersect->all();
// ['size' => 'M']
intersectByKeys()
intersectByKeys
メソッドは、指定した配列またはコレクションに存在しないキーとそれに対応する値を元のコレクションから削除します。
$collection = collect([
'serial' => 'UX301', 'type' => 'screen', 'year' => 2009,
]);
$intersect = $collection->intersectByKeys([
'reference' => 'UX404', 'type' => 'tab', 'year' => 2011,
]);
$intersect->all();
// ['type' => 'screen', 'year' => 2009]
isEmpty()
isEmpty
メソッドはコレクションが空の場合にtrue
を返します。そうでなければfalse
を返します。
collect([])->isEmpty();
// true
isNotEmpty()
isNotEmpty
メソッドは、コレクションが空でない場合にtrue
を返します。空であればfalse
を返します。
collect([])->isNotEmpty();
// false
join()
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()
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()
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()
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()
lazy
メソッドは、アイテムの配列から新しいレイジーコレクションインスタンスを返します。
$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
)に変換することで、追加で大量のメモリを確保する必要がなくなります。元のコレクションはメモリ内に自身の値(its)を保持しますが、後続するフィルタは保持しません。そのため、コレクションへフィルタをかけるとき、追加のメモリが割り当てられることはありません。
macro()
staticのmacro
メソッドで、実行時にCollection
クラスへメソッドを追加できます。詳細は、コレクションの拡張ドキュメントを参照してください。
make()
staticのmake
メソッドは、新しいコレクションインスタンスを生成します。コレクションの生成セクションを参照してください。
map()
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]
Warning!! 他のコレクションと同様に
map
は新しいコレクションインスタンスを返します。呼び出し元のコレクションは変更しません。もしオリジナルコレクションを変更したい場合はtransform
メソッドを使います。
mapInto()
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()
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()
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()
mapWithKeys
メソッドはコレクション全体を反復処理し、指定したコールバックへ各値を渡します。コールバックからキー/値ペアを一つ含む連想配列を返してください。
$collection = collect([
[
'name' => 'John',
'department' => 'Sales',
'email' => 'john@example.com',
],
[
'name' => 'Jane',
'department' => 'Marketing',
'email' => 'jane@example.com',
]
]);
$keyed = $collection->mapWithKeys(function (array $item, int $key) {
return [$item['email'] => $item['name']];
});
$keyed->all();
/*
[
'john@example.com' => 'John',
'jane@example.com' => 'Jane',
]
*/
max()
max
メソッドは、指定したキーの最大値を返します。
$max = collect([
['foo' => 10],
['foo' => 20]
])->max('foo');
// 20
$max = collect([1, 2, 3, 4, 5])->max();
// 5
median()
median
メソッドは、指定したキーの中央値を返します。
$median = collect([
['foo' => 10],
['foo' => 10],
['foo' => 20],
['foo' => 40]
])->median('foo');
// 15
$median = collect([1, 1, 2, 4])->median();
// 1.5
merge()
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()
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()
min
メソッドは、指定したキーの最小値を返します。
$min = collect([['foo' => 10], ['foo' => 20]])->min('foo');
// 10
$min = collect([1, 2, 3, 4, 5])->min();
// 1
mode()
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()
nth
メソッドは指定数値間隔で要素を含む、新しいコレクションを生成します。
$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']);
$collection->nth(4);
// ['a', 'e']
オプションで、2番目の引数として開始オフセットを指定できます。
$collection->nth(4, 1);
// ['b', 'f']
only()
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メソッドです。
Note: Eloquentコレクションの使用時は、このメソッドの振る舞いは変わります。
pad()
pad
メソッドは、配列が指定したサイズに達するまで、指定値で配列を埋めます。このメソッドはarray_pad
PHP関数のような動作をします。
先頭を埋めるためには、サイズに負数を指定します。配列サイズ以下のサイズ値を指定した場合は、埋め込みを行いません。
$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()
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()
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()
pipe
メソッドは、コレクションを指定したクロージャに渡し、実行されたクロージャの結果を返します。
$collection = collect([1, 2, 3]);
$piped = $collection->pipe(function (Collection $collection) {
return $collection->sum();
});
// 6
pipeInto()
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()
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()
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()
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()
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()
pull
メソッドはキーによりアイテムを削除し、そのアイテムを返します。
$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']);
$collection->pull('name');
// 'Desk'
$collection->all();
// ['product_id' => 'prod-100']
push()
push
メソッドはコレクションの最後にアイテムを追加します。
$collection = collect([1, 2, 3, 4]);
$collection->push(5);
$collection->all();
// [1, 2, 3, 4, 5]
put()
put
メソッドは指定したキーと値をコレクションにセットします。
$collection = collect(['product_id' => 1, 'name' => 'Desk']);
$collection->put('price', 100);
$collection->all();
// ['product_id' => 1, 'name' => 'Desk', 'price' => 100]
random()
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] - (retrieved randomly)
range()
range
メソッドは、指定範囲の整数を含むコレクションを返します。
$collection = collect()->range(3, 6);
$collection->all();
// [3, 4, 5, 6]
reduce()
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()
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()
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()
replace
メソッドは、merge
メソッドと似た振る舞いを行います。文字列キーを持っているアイテムをオーバーライドするのは同じですが、replace
メソッドは数値キーに一致するコレクション中のアイテムもオーバーライドします。
$collection = collect(['Taylor', 'Abigail', 'James']);
$replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']);
$replaced->all();
// ['Taylor', 'Victoria', 'James', 'Finn']
replaceRecursive()
このメソッドはreplace
と似た動作をしますが、配列を再帰的に下り、次元の低い値も同様に置換します。
$collection = collect([
'Taylor',
'Abigail',
[
'James',
'Victoria',
'Finn'
]
]);
$replaced = $collection->replaceRecursive([
'Charlie',
2 => [1 => 'King']
]);
$replaced->all();
// ['Charlie', 'Abigail', ['James', 'King', 'Finn']]
reverse()
reverse
メソッドはオリジナルのキーを保ったまま、コレクションのアイテムの順番を逆にします。
$collection = collect(['a', 'b', 'c', 'd', 'e']);
$reversed = $collection->reverse();
$reversed->all();
/*
[
4 => 'e',
3 => 'd',
2 => 'c',
1 => 'b',
0 => 'a',
]
*/
search()
search
メソッドは、コレクションを検索し、指定値が見つかった場合はそのキーを返します。アイテムが見つからない場合、false
を返します。
$collection = collect([2, 4, 6, 8]);
$collection->search(4);
// 1
検索は「緩い」比較で行われます。つまり、整数値を持つ文字列は、同じ値の整数に等しいと判断されます。「厳格」な比較を行いたい場合はtrue
をメソッドの第2引数に渡します。
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
shift()
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()
shuffle
メソッドはコレクションのアイテムをランダムにシャッフルします。
$collection = collect([1, 2, 3, 4, 5]);
$shuffled = $collection->shuffle();
$shuffled->all();
// [3, 2, 5, 1, 4] - (ランダムに生成される)
skip()
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()
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]
Warning!! 指定した値が見つからないか、コールバックが
true
を返さなかった場合、skipUntil
メソッドは空のコレクションを返します。
skipWhile()
skipWhile
メソッドは、指定したコールバックがtrue
を返す間、コレクションからアイテムをスキップし、コレクション内の残りのアイテムを新しいコレクションとして返します。
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipWhile(function (int $item) {
return $item <= 3;
});
$subset->all();
// [4]
Warning!! コールバックが
false
を返さなかった場合、skipWhile
メソッドは空のコレクションを返します。
slice()
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]
sliceメソッドはデフォルトでキー値を保持したまま返します。オリジナルのキーを保持したくない場合は、values
メソッドを使えば、インデックスし直されます。
sliding()
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;
});
必要に応じて、それぞれのチャンクの最初の項目間にどのくらい距離を取るかを決定する2番目の「ステップ」値を渡せます。
$collection = collect([1, 2, 3, 4, 5]);
$chunks = $collection->sliding(3, step: 2);
$chunks->toArray();
// [[1, 2, 3], [3, 4, 5]]
sole()
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]
もしくは、要素が1つしかない場合は、引数を指定せずにsole
メソッドを呼び出すこともできます。
$collection = collect([
['product' => 'Desk', 'price' => 200],
]);
$collection->sole();
// ['product' => 'Desk', 'price' => 200]
コレクション内に、sole
メソッドが返すべき要素がない場合、\Illuminate\Collections\ItemNotFoundException
例外を投げます。返すべき要素が複数ある場合は、\Illuminate\Collections\MultipleItemsFoundException
を投げます。
some()
contains
メソッドのエイリアスです。
sort()
sort
メソッドはコレクションをソートします。ソート済みコレクションはオリジナル配列のキーを保持しますので、以下の例では、values
メソッドにより、連続した数字のインデックスにするためリセットしています。
$collection = collect([5, 3, 1, 2, 4]);
$sorted = $collection->sort();
$sorted->values()->all();
// [1, 2, 3, 4, 5]
より高度なソートを行いたい場合はsort
にコールバックを渡し、自分のアルゴリズムを実行できます。コレクションのsort
メソッドが使用しているuasort
のPHPドキュメントを参照してください。
Note: ネストした配列やオブジェクトのコレクションのソートは、
sortBy
とsortByDesc
メソッドを参照してください。
sortBy()
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']],
]
*/
コレクションを複数の属性で並べ替える場合は、並べ替え操作の配列を
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()
このメソッドの使い方はsortBy
と同じで、コレクションを逆順にソートします。
sortDesc()
このメソッドはsort
メソッドの逆順でコレクションをソートします。
$collection = collect([5, 3, 1, 2, 4]);
$sorted = $collection->sortDesc();
$sorted->values()->all();
// [5, 4, 3, 2, 1]
sort
とは異なり、sortDesc
にクロージャを渡すことはできません。代わりに、sort
メソッドを使用して、比較を逆にする必要があります。
sortKeys()
sortKeys
メソッドは、内部の連想配列のキーにより、コレクションをソートします。
$collection = collect([
'id' => 22345,
'first' => 'John',
'last' => 'Doe',
]);
$sorted = $collection->sortKeys();
$sorted->all();
/*
[
'first' => 'John',
'id' => 22345,
'last' => 'Doe',
]
*/
sortKeysDesc()
このメソッドは、sortKeys
メソッドと使い方は同じですが、逆順にコレクションをソートします。
sortKeysUsing()
sortKeysUsing
メソッドはコールバックを用いて、連想配列のキーでコレクションをソートします。
$collection = collect([
'ID' => 22345,
'first' => 'John',
'last' => 'Doe',
]);
$sorted = $collection->sortKeysUsing('strnatcasecmp');
$sorted->all();
/*
[
'first' => 'John',
'ID' => 22345,
'last' => 'Doe',
]
*/
コールバックは0か、0より小さいか、0より大きい整数を返す比較関数でなければなりません。詳細については、uksort
のPHPドキュメントを参照してください。この関数はsortKeysUsing
メソッドが内部で利用しているPHP関数です。
splice()
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()
split
メソッドは、コレクションを指定数のグループへ分割します。
$collection = collect([1, 2, 3, 4, 5]);
$groups = $collection->split(3);
$groups->all();
// [[1, 2], [3, 4], [5]]
splitIn()
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()
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()
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()
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]
Warning!! 指定値が見つからない、もしくはコールバックが
true
を返さない場合、takeUntil
メソッドはコレクションの全アイテムを返します。
takeWhile()
takeWhile
メソッドは、指定のコールバックがfalse
を返すまでコレクションのアイテムを返します。
$collection = collect([1, 2, 3, 4]);
$subset = $collection->takeWhile(function (int $item) {
return $item < 3;
});
$subset->all();
// [1, 2]
Warning!! コールバックが
false
を返さない場合、takeWhile
メソッドはコレクション中の全アイテムを返します。
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()
静的times
メソッドは指定回数クロージャを呼び出すことで、新しいコレクションを生成します。
$collection = Collection::times(10, function (int $number) {
return $number * 9;
});
$collection->all();
// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
toArray()
toArray
メソッドはコレクションをPHPの「配列」へ変換します。コレクションの値がEloquentモデルの場合は、そのモデルが配列に変換されます。
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toArray();
/*
[
['name' => 'Desk', 'price' => 200],
]
*/
Warning!!
toArray
は、ネストしたArrayable
インスタンスのオブジェクトすべてを配列へ変換します。コレクションの裏の素の配列をそのまま取得したい場合は、代わりにall
メソッドを使用してください。
toJson()
toJson
メソッドはコレクションをシリアライズ済みのJSON文字へ変換します。
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toJson();
// '{"name":"Desk","price":200}'
transform()
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]
Warning!! 他のコレクションメソッドとは異なり、
transform
はコレクション自身を更新します。代わりに新しいコレクションを生成したい場合は、map
メソッドを使用してください。
undot()
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()
union
メソッドは指定した配列をコレクションへ追加します。すでにコレクションにあるキーが、オリジナル配列に含まれている場合は、オリジナルコレクションの値が優先されます。
$collection = collect([1 => ['a'], 2 => ['b']]);
$union = $collection->union([3 => ['c'], 1 => ['d']]);
$union->all();
// [1 => ['a'], 2 => ['b'], 3 => ['c']]
unique()
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
メソッドを使用してください。
Note: Eloquentコレクションの使用時は、このメソッドの振る舞いは変わります。
uniqueStrict()
このメソッドは、unique
と同じ使用方法です。しかし、全値は「厳密」に比較されます。
unless()
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]
2つ目のコールバックをunless
メソッドへ指定できます。2つ目のコールバックは、unless
メソッドへ渡した最初の引数がtrue
と評価されたときに実行します。
$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()
whenNotEmpty
メソッドのエイリアスです。
unlessNotEmpty()
whenEmpty
メソッドのエイリアスです。
unwrap()
staticのunwrap
メソッドは適用可能な場合、指定値からコレクションの元になっているアイテムを返します。
Collection::unwrap(collect('John Doe'));
// ['John Doe']
Collection::unwrap(['John Doe']);
// ['John Doe']
Collection::unwrap('John Doe');
// 'John Doe'
value()
value
メソッドは、コレクション内の最初の要素から、指定した値を取得します。
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Speaker', 'price' => 400],
]);
$value = $collection->value('price');
// 200
values()
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()
when
メソッドは、メソッドの第1引数がtrue
に評価される場合、コールバックを実行します。コレクションインスタンスとwhen
メソッドに指定した第1引数をクロージャへ渡します。
$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]
2つ目のコールバックをwhen
メソッドへ指定できます。2番目のコールバックは、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()
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()
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()
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()
このメソッドの使用法は、where
メソッドと同じです。しかし、値の比較はすべて「厳格」な比較で行います。
whereBetween()
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()
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()
このメソッドの使い方は、whereIn
メソッドと同じです。違いは全値を「厳密」に比較することです。
whereInstanceOf()
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()
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()
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()
このメソッドは、whereNotIn
と使い方は同じですが、全値の比較が「厳密」に行われる点が異なります。
whereNotNull()
wherenotnull
メソッドは、与えられたキーがnull
ではないアイテムをコレクションから返します。
$collection = collect([
['name' => 'Desk'],
['name' => null],
['name' => 'Bookcase'],
]);
$filtered = $collection->whereNotNull('name');
$filtered->all();
/*
[
['name' => 'Desk'],
['name' => 'Bookcase'],
]
*/
whereNull()
whernull
メソッドは、与えられたキーがnull
のアイテムをコレクションから返します。
$collection = collect([
['name' => 'Desk'],
['name' => null],
['name' => 'Bookcase'],
]);
$filtered = $collection->whereNull('name');
$filtered->all();
/*
[
['name' => null],
]
*/
wrap()
staticの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()
zip
メソッドは指定した配列の値と、対応するインデックスのオリジナルコレクションの値をマージします。
$collection = collect(['Chair', 'Desk']);
$zipped = $collection->zip([100, 200]);
$zipped->all();
// [['Chair', 100], ['Desk', 200]]
Higher Orderメッセージ
コレクションで繁用するアクションを手短に実行できるよう、"Higher
Orderメッセージ"をサポートしました。average
、avg
、contains
、each
、every
、filter
、first
、flatMap
、groupBy
、keyBy
、map
、max
、min
、partition
、reject
、skipUntil
、skipWhile
、some
、sortBy
、sortByDesc
、sum
、unique
、takeUntil
、takeWhile
コレクションメソッドでHigher
Orderメッセージが使用できます。
各Higher
Orderメッセージへは、コレクションインスタンスの動的プロパティとしてアクセスできます。例として、コレクション中の各オブジェクトメソッドを呼び出す、each
Higher Orderメッセージを使用してみましょう。
use App\Models\User;
$users = User::where('votes', '>', 500)->get();
$users->each->markAsVip();
同様に、ユーザーのコレクションに対し、「投票(votes)」の合計数を求めるために、sum
Higher Orderメッセージを使用できます。
$users = User::where('group', 'Development')->get();
return $users->sum->votes;
レイジーコレクション
イントロダクション
Warning!! Laravelのレイジーコレクションを学ぶ前に、PHPジェネレータに慣れるために時間を取ってください。
すでに強力なCollection
クラスを補足するために、LazyCollection
クラスはPHPのPHPジェネレータを活用しています。巨大なデータセットをメモリ使用を抑えて利用する目的のためです。
たとえば、アプリケーションで数ギガバイトのログを処理する必要があり、ログを解析するためにLaravelのコレクションメソッドを活用するとしましょう。ファイル全体をメモリへ一度で読み込む代わりに、レイジーコレクションなら毎回ファイルの小さな部分だけをメモリに保持するだけで済みます。
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つのクエリを実行するだけでなく、一度に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;
}
レイジーコレクションの生成
レイジーコレクションインスタンスを生成するには、コレクションのmake
メソッドへPHPジェネレータ関数を渡します。
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
契約を実装しており、以下のメソッドを定義しています。
Warning!!
shift
、pop
、prepend
などのように、コレクションを変異させるメソッドは、LazyCollection
クラスでは使用できません。
レイジーコレクションメソッド
Enumerable
契約で定義しているメソッドに加え、LazyCollection
クラス契約は以下のメソッドを含んでいます。
takeUntilTimeout()
takeUntilTimeout
メソッドは、指定された時間まで値を列挙する新しいレイジーコレクションを返します。その後、コレクションは列挙を停止します。
$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()
each
メソッドはコレクション中の各アイテムに対し、指定したコールバックを即時に呼び出しますが、tapEach
メソッドはリストから一つずつアイテムを抜き出し、指定したコールバックを呼び出します。
// これまでに何もダンプされていない
$lazyCollection = LazyCollection::times(INF)->tapEach(function (int $value) {
dump($value);
});
// 3アイテムがダンプ
$array = $lazyCollection->take(3)->all();
// 1
// 2
// 3
remember()
remember
メソッドは、すでに列挙されている値を記憶し、後続のコレクション列挙でそれらを再度取得しない新しいレイジーコレクションを返します。
// まだ、クエリは実行されない
$users = User::cursor()->remember();
// クエリは実行された
// 最初の5人のユーザーがデータベースからハイドレイト
$users->take(5)->all();
// 最初の5人のユーザーはコレクションのキャッシュから取得
// 残りはデータベースからハイドレイト
$users->take(20)->all();