🍟

Laravelでin_arrayを用いた条件分岐する際のtips

2023/05/23に公開

結論

in_arrayで検索するより、配列のキーを用いてisset()で検索する方が早い。
そのためのCollectionでのデータの取得方法

$target = 'banana';
$items = ['apple', 'banana', 'grape'];
$collectedItems = collect($items);
$flippedItems = $collectedItems->flip()->all();
isset($flippedItems[$target]); // true

flip()->all() で取得可能。
ただし、$items のようなデータをpluckで取得する場合は改善可能

$target = 'banana';  
$items = [  
    ['name' => 'apple', 'color' => 'red'],  
    ['name' => 'banana', 'color' => 'yellow'],  
    ['name' => 'grape', 'color' => 'purple'],  
];  
$collectedItems = collect($items);  
$flippedItems = $collectedItems->pluck(null, 'name');
isset($flippedItems[$target]); // true

pluckの第二引数に取得したい項目を指定すると取得できる。

説明

PHPにはin_arrayという関数があります。
変数が配列内に存在するかどうかをチェックするものです。

$target = 'banana';
$items = ['apple', 'banana', 'grape'];
in_array($target, $items, true); // true

数件程度であれば問題ないのですが、配列の件数が多くなるとパフォーマンスが悪くなります。
また、ループ内で繰り返し呼び出すとそれが顕著に現れます。
対応法としては、チェックしたい項目をキーに持たせそこでチェックすることで改善できます。

$target = 'banana';
$items = ['apple', 'banana', 'grape'];
$flippedItems = array_flip($items);
isset($flippedItems[$target]); // true

このようにarray_flipという関数を用いることで、キーと値を入れ替えキーでチェックできるようになりました。
ただ、入れ替えるコストもあるので全ての場合に適しているわけではなく、要素数が多く、またループの中でチェックを行う場合等、状況を考えて使う必要がありそうです。

Laravelを使っていると、このような大量の要素はCollectionで存在してることが多いと思うので、その場合の方法です。

$target = 'banana';
$items = ['apple', 'banana', 'grape'];
$collectedItems = collect($items);
$flippedItems = $collectedItems->flip()->all();
isset($flippedItems[$target]); // true

$collectedItemsのような形にpluck等で取得して、flip()->all()を使ってあげると便利かと思います。
もう少し、実践的なものだと

$target = 'banana';
$items = [  
    ['name' => 'apple', 'color' => 'red'],  
    ['name' => 'banana', 'color' => 'yellow'],  
    ['name' => 'grape', 'color' => 'purple'],  
];
$collectedItems = collect($items);
$flippedItems = $collectedItems->pluck('name')->flip()->all();
isset($flippedItems[$target]); // true

このような感じに、pluckで必要な配列を作成して、という前作業が発生するかと思います。

ただ、この場合であればもう少し改善できます。

$target = 'banana';  
$items = [  
    ['name' => 'apple', 'color' => 'red'],  
    ['name' => 'banana', 'color' => 'yellow'],  
    ['name' => 'grape', 'color' => 'purple'],  
];  
$collectedItems = collect($items);  
$flippedItems = $collectedItems->pluck(null, 'name');
isset($flippedItems[$target]); // true

このようにpluckの時点で値をnullに設定し、キーに取得したい値を入れる方法もあります。
こうすることで、処理を減らすことができます。

Collectionの時点でデータの取り方を工夫することで、記述の冗長化を防いだり、処理速度の向上が期待できると思います。

また、何度も言いますが、要素数が数件程度であったり繰り返さないものに関してはあまり気にする必要はないと思うので、状況を考えて使っていければと思います。

株式会社THIRD エンジニアブログ

Discussion