結論
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の時点でデータの取り方を工夫することで、記述の冗長化を防いだり、処理速度の向上が期待できると思います。
また、何度も言いますが、要素数が数件程度であったり繰り返さないものに関してはあまり気にする必要はないと思うので、状況を考えて使っていければと思います。
Discussion