Eloquentコレクションに固有の質問ではないかもしれませんが、コレクションを操作していると、私に衝撃を与えます。 _$collection
_のインスタンスである_Illuminate\Support\Collection
_オブジェクトがあると仮定しましょう。
ここで繰り返したい場合、クロージャと通常のforeach
を使用してeach()
を使用することの長所と短所は何ですか。何かありますか?
_foreach ($collection as $item) {
// Some code
}
--- VS ---
$collection->each(function ($item) {
// Some code
});
_
foreach
ステートメントは、コレクションを循環し、コレクションに対して何らかのロジックを実行する一種の方法として使用する必要があります。その中にあるものがプログラムの他の事柄に影響する場合、このループを使用します。
_.each
_メソッドは、_array_map
_を使用して、コレクション内の各オブジェクトを循環させ、各オブジェクトに対してクロージャを実行します。次に、結果の配列を返します。それが鍵です!何らかの方法でコレクションを変更する場合は、_.each
_を使用する必要があります。多分それは車の配列であり、モデルを大文字または小文字にする必要があります。オブジェクトを取り、各Carオブジェクトのモデルでstrtoupper()
を呼び出す_.each
_メソッドにクロージャーを渡すだけです。次に、行われた変更を含むコレクションを返します。
物語のモラールは次のとおりです。_.each
_メソッドを使用して、配列の各項目を何らかの方法で変更します。 foreach
ループを使用して各オブジェクトを使用し、プログラムの他の部分に影響を与えます(ロジックステートメントを使用)。
以下のように(私がそこで何をしたかを参照してください)雄弁に述べたように、上記の答えは少しずれています。 _.each
_を使用する_array_map
_メソッドは、実際に_array_map
_呼び出しからの出力を使用しませんでした。したがって、_array_map
_によって作成された新しい配列は、Collection
に保存されません。変更するには、Collection
オブジェクトにも存在する_.map
_メソッドを使用することをお勧めします。
foreach
ステートメントを使用することは、use
ステートメントを使用していることを確認しない限り、クロージャーの外部の変数にアクセスできないため、少しずつ理にかなっています。気まずい。
上記の回答が最初に記述されたときの実装は、 ここにあります になります。
.each
_ in Laravel 5.1以下で説明している新しい_.each
_は、_array_map
_を使用しなくなりました。コレクション内の各アイテムを繰り返し処理し、渡された_$callback
_を呼び出して、アイテムと配列内のキーを渡します。機能的には、同じように動作するようです。コードを読むとき、foreach
ループを使用する方が理にかなっていると思います。ただし、_.each
_を使用する利点は、それがあなたの空想をくすぐる場合にメソッドを一緒に連鎖させることができるためです。また、ビジネスロジックでできるようにする必要がある場合、コールバックからfalseを返してループを早期に終了することもできます。
新しい実装の詳細については、 ソースコード をご覧ください。
既存の回答には、多くの紛らわしい誤報があります。
簡単な答えは次のとおりです。.each()
とforeach
を使用してLaravelコレクションを繰り返し処理する)には大きな違いはありません。どちらの手法でも同じ結果が得られます。
アイテムを変更するかどうかは、.each()
対foreach
を使用するかどうかとは無関係です。どちらも、私たちが話しているアイテムの種類に応じて、コレクション内のアイテムを変更することができます(できません!)。
.each()
またはforeach
を使用すると、オブジェクトのプロパティを変更できます(_$item->name = 'foo'
_など)。これは、単にPHPオブジェクトが常に参照のように機能するためです。オブジェクト全体を別のオブジェクトに置き換えるには(あまり一般的ではないシナリオ)、代わりに.map()
を使用します。.each()
は方法を提供しませんコレクションアイテムの値を変更します。 (クロージャの戻り値は無視されます。)代わりに.map()
を使用してください。パフォーマンスについて疑問がある場合は、Eloquentアイテムと文字列のコレクションの両方の大規模なコレクションでいくつかのテストを行いました。どちらの場合も、foreach
の使用は.each()
よりも高速でした。しかし、私たちはマイクロ秒について話している。ほとんどの実際のシナリオでは、データベースなどにアクセスするのにかかる時間と比較して、速度の差はそれほど大きくありません。
それは主に個人的な好みに帰着します。 .each()
を使用すると、複数の操作(たとえば、.where(...).each(...)
)をチェーン化できるため便利です。私はそれぞれの状況で最もきれいに見えるものに応じて、自分のコードで両方を使用する傾向があります。
技術的に言えば、他の2つの答えが言っているのとは反対に、Collection::each()
はnotでコレクション内のアイテムの値を変更します。 array_map()
を使用しますが、その呼び出しの結果は保存しません。
コレクション内の各アイテムを変更したい場合(たとえば、現在受け入れられている回答へのコメントでDamonとしてオブジェクトにキャストする場合)、Collection::map()
を使用する必要があります。これにより、array_map()
の基礎となる呼び出しの結果に基づいて新しいコレクションが作成されます。
後者のeach()を使用する方がより有益です。
条件を連鎖させて、より明確で表現力豊かなコードを書くことができます。例:
$ example-> each()-> map()-> filter();
これにより、どのように達成するかではなく、何を達成するかをコンピューターに指示する宣言型プログラミングに近づきます。
役に立つ記事: