web-dev-qa-db-ja.com

laravel雄弁なコレクションのArray_unique

これが可能かどうかはわかりませんが、重複を削除するために、持っているアイテムのコレクションに対してarray_uniqueを実行しようとしています。私はそれを動作させることはできませんが。

私のコントローラーロジック:

    // init models
    $jobs = Job::search();
    $countries = $jobs->get()->map(function( $job ) {

        return $job->country;
    });
    $countries = array_unique( $countries->toArray() );

これは「配列から文字列への変換」エラーを受け取りますが

13
AndrewMcLagan

Select句で distinctまたはgroup by を使用して、DB結果に一意の値を含めることができます。ただし、reallyがオブジェクトの配列に対して一意の値を必要とする場合は、以下を実行できます。

$uniques = array();
foreach ($countries as $c) {
    $uniques[$c->code] = $c; // Get unique country by code.
}

dd($uniques);
1
Rubens Mariuzzo

CollectionクラスのUniqueメソッドを試すことができます。

$countries = $countries->unique();

Collectionクラスにはいくつかの素晴らしいメソッドがあります。これについては Laravel APIドキュメント で読むことができます。

たとえば、最初にカウントしてからフィルター処理したい場合のように、(Querybuilderクラスを使用してデータベースで別のクエリを実行する代わりに)メモリ内の既存のコレクションを「クエリ」する方が効率的である場合があることに同意します。 .NET LINQでは、データベースと同じようにIEnumerable(メモリ内コレクション)でクエリを実行できます。

31
Jorr.it

私は同様の問題を抱えていましたが、今日誰かに役立つかもしれないので時間が経ちましたが。

私が抱えていた問題は、アイテムのコレクションに対してuniqueメソッドを呼び出したときに機能しなかったということでした。これがおそらく最初の回答が受け入れられた理由です。したがって、モデルがあり、特定のフィールドに基づいて重複を削除したい場合は、uniqueメソッドにパラメーターを渡すことができます。この場合は、次のようになります。

$countries->unique('code');

そうすることで、一意のコードを持つ国のみが存在するようになります。最初の値しか残っていないことに気付くかもしれません。そのため、ショッピングカートアプリケーションを開発し、何らかの理由でカートをマージし、最近のアイテムだけを持ちたい場合は、コレクションを元に戻し、uniqueを呼び出して元に戻すことができます。 :

$countries->reverse()->unique('code')->reverse(); // it doesn't really make sense in this example though

それはおそらく最良のオプションではなく、データベース側でフィルタリングを行う方が良いですが、オプションがあることは素晴らしいことです。

6
orustammanapov

それがまさにあなたがやりたいことなら、雄弁なコレクションでfilterメソッドを試すことができます

http://laravel.com/docs/eloquent#collections

0
kaning