PHPでサイト制作をする場合、たいてい「検索」がつきものです。
(PHPに限らず、サイトにプログラムを盛り込む場合はですが)
データベースを検索する場合は、SQL文を駆使すれば良い話です。
ただ今回、PHPで作成した2次元配列から該当する記述を探すという事例がありました。
用途としては、事前にPHPの2次元配列に設定を記述しておき、後から該当する設定を取り出すような場合です。
一見簡単そうに思ったのですが、意外とそうでもなかったため、忘備録として記録します。
今回のお題
下記の2次元配列から「no」が「5」の「name」である「b02」を取り出す。
<?php
$table = array(
array("no"=>1, "name"=>"a01"),
array("no"=>2, "name"=>"a02"),
array("no"=>3, "name"=>"a03"),
array("no"=>4, "name"=>"b01"),
array("no"=>5, "name"=>"b02"),
array("no"=>6, "name"=>"b03"),
array("no"=>7, "name"=>"c01"),
array("no"=>8, "name"=>"c02"),
array("no"=>9, "name"=>"c03")
);
目で見ると簡単ですが、これをPHPの記述で実現しようと思うと、頭をひねりました。
ループ処理で探せばそれでよいのかもしれませんが、もっとスマートにできないかと考えたからです。
1次元配列の場合はarray_search関数ですが2次元配列で使用するとうまくいきません
PHPには配列内を検索する関数があります。
array_search関数です。
ですが、array_search関数は1次元配列にしか対応していません。
ちなみに以下のような記述をしてみたところ、該当なしとなりました。
$key = array_search(5, $table);
ググるとarray_column関数を組み合わせるというやり方がありました
array_searchは1次元配列内を検索する関数です。
そのため、2次元配列は検索できません。
何とかする方法をググっていたところ、次のようなやり方がありました。
2次元配列を1次元に変換してarray_searchを使う。
コロンブスの卵的な発想ですが、やってみるとうまくいきました。
記述は次の通りです。
<?php
$table = array(
array("no"=>1, "name"=>"a01"),
array("no"=>2, "name"=>"a02"),
array("no"=>3, "name"=>"a03"),
array("no"=>4, "name"=>"b01"),
array("no"=>5, "name"=>"b02"),
array("no"=>6, "name"=>"b03"),
array("no"=>7, "name"=>"c01"),
array("no"=>8, "name"=>"c02"),
array("no"=>9, "name"=>"c03")
);
$key = array_search(5, array_column($table, "no"));
$name = $table[$key]["name"];
$keyには、「name」「b02」を示す配列位置「4」がセットされました。
つまり、$table[$key]と記述すれば、「b02」を取り出せます。
array_columnって何?
array_column関数って聞きなれない関数です。
マニュアルを見ても、いまいちぴんときません。
ざっくりいうと、2次元配列の1カラムを抽出して1次元配列に変換する機能です。
今回の場合「no」を検索するため、array_column関数で「no」カラムを抽出して1次元配列に変換しています。
1次元配列になれば、array_search関数で検索できます。
なんともうまい方法があったものです。
今回はこの方法で解決することができました。
注意点:この方法では複数検索はできません。
データベースを検索する場合は、該当するものが複数あった場合、一度にすべて抽出することができます。
ですが、今回のarray_column関数とarray_serach関数を組み合わせる方式だと、最初に一致したものしか検索できませんでした。
用途としては、同一番号が存在しないテーブル検索向けの方法になります。
どうしても複数検索する場合は、ループ処理を駆使して組む方法になります。
ちなみに3次元配列では検索できませんでした。
3次元配列はあまり使うことはありませんが、試しに次の配列で検索できるか試してみましたが、さすがに検索できませんでした。
今回の方法は2次元配列限定の方法でした。
<?php
$table = array(
array(
array("no"=>1, "name"=>"a01"),
array("no"=>2, "name"=>"a02"),
array("no"=>3, "name"=>"a03")
),
array(
array("no"=>4, "name"=>"b01"),
array("no"=>5, "name"=>"b02"),
array("no"=>6, "name"=>"b03")
),
array(
array("no"=>7, "name"=>"c01"),
array("no"=>8, "name"=>"c02"),
array("no"=>9, "name"=>"c03")
)
);
array_column関数は2次元配列からしか抽出できないため、3次元配列は無理でした。
ちなみに、3次元配列をループ処理を使って実現したサンプルが以下になります。
for($posi=0 ; $posi < sizeof($table) ; $posi++)
{
$key = array_search(5, array_column($table[$posi], "no"));
if ($key != false)
{
// 配列ポジションを記憶
$primary = $posi;
$secondary = $key;
break;
}
}
$name = $table[$primary][$secondary]["name"];
この方法も最初に一致したものしか検索しないため、検索対象が複数ある場合には向きません。
結局最終的にはループ処理になるのか。と思いましたが、2次元配列までならばループ処理がなくても探せることがわかりました。
また参考になれば幸いです。