多次元配列に特定の値があるか確認することよくありますよね。
何回書いても忘れて毎回調べちゃうのでメモメモ。
やりたかったこと、私が書いた方法、*in_array()*で書いた方法もメモで載せておきます。
#書き方
##1次配列の場合
書き方
in_array( 検索文字列 , 検索対象の配列 );
使用例
$array= ['山田', '佐藤', '鈴木'];
var_dump(in_array('山田', $array)); // 結果:true
var_dump(in_array('田中', $array)); // 結果:false
##多次元配列の場合
書き方
in_array( 検索文字列, array_column( 検索対象の配列 , 検索する配列のキー ));
使用例
$array = [
['name' => '山田', 'age' => '20'],
['name' => '佐藤', 'age' => '25'],
['name' => '鈴木', 'age' => '30']
];
var_dump(in_array('山田', array_column($array, 'name'))); // 結果:true
var_dump(in_array('田中', array_column($array, 'name'))); // 結果:false
##array_columnってなんや
引数に渡した配列の中から、単一のカラムを取り出すための関数
らしいです。array_columnは名前だけ知ってたけど使ったことがなかったです。なんと愚かなことでしょう。
以下のように使用します。
array_column ( 検索対象の配列 , 取り出したいkey )
つま先ほど書いた多次元配列内の存在チェックは、指定したkeyの値を取り出してin_arrayで存在チェックをしているということですね。
#やりたかったこと
DBからとってきたデータを、特定のkeyごとにまとめた多次元配列を作る、というのをやりたかった。
例えばDBからとってきた、以下のようなデータがあるとします。
適当にコピペをもとに作ったデータですが、名前と性別の情報をもっているとします。
array(4) {
[0]=>
array(3) {
["id"] => 1,
["sex_id"] => 1,
["name"] => "sample1"
}
[1]=>
array(3) {
["id"] => 2,
["sex_id"] => 1,
["name"] => "sample2"
}
[2]=>
array(3) {
["id"] => 3,
["sex_id"] => 2,
["name"] => "sample3"
}
[3]=>
array(3) {
["id"] => 4,
["sex_id"] => 2,
["name"] => "sample4"
}
}
それをこんな感じに成形したい
member_list: [
{
sex_id: 1,
name_list: [
{
id: 1,
name: "sample1"
},
{
id: 2,
name: "sample2"
}
]
},
{
sex_id: 2,
name_list: [
{
id: 3,
name: "sample3"
},
{
id: 4,
name: "sample4"
}
]
},
]
##foreachで書いた場合
phpの実務経験が浅かった私はforeachで書いてました。なんと愚かなことでしょう。
こんな感じで書いてました(動かしてないので間違いあったらすみません)
//データを$mst_memberとします
$member_list = array();
foreach($mst_member as $member) {
$is_sex = false;
$index = 0;
// sex_idの存在チェックとindexの取得
foreach ($member_list as $member_list){
if ($member_list['sex_id'] == $member['sex_id']){
$is_sex = true;
break;
}
$index++;
}
$name_list_info = array();
$name_list_info ['id'] = $member['id'];
$name_list_info ['name'] = $member['name'];
if ($is_sex){
array_push($member_list[$index]['name_list'], $name_list_info);
} else {
$member_list_info = array();
$member_list_info ['sex_id'] = $member['sex_id'];
$member_list_info ['name_list'] = array();
array_push($member_list_info ['name_list'], $name_list_info);
array_push($member_list, $member_list_info );
}
}
##in_arrayで書いた場合
先ほどかいた多次元配列のin_arrayを使って書いてみます
//データを$mst_memberとします
$member_list = array();
foreach($mst_member as $member) {
$name_list_info = array();
$name_list_info ['id'] = $member['id'];
$name_list_info ['name'] = $member['name'];
if(in_array($member['sex_id'], array_column($member_list, 'sex_id'))){
// indexを取得
$index = array_search($member['sex_id'], array_column($member_list, 'sex_id'));
array_push($member_list[$index]['name_list'], $name_list_info);
} else {
$member_list_info = array();
$member_list_info ['sex_id'] = $member['sex_id'];
$member_list_info ['name_list'] = array();
array_push($member_list_info ['name_list'], $name_list_info);
array_push($member_list, $member_list_info );
}
}
array_columnの使い方がわかったのでarray_searchと合わせて使うことでindexの取得もでき、すっきり書けました。
ループも1つになりましたね。
今回はphpなのでよかったけど、C#とかで多次元配列の操作しようと思うとなかなか難しいことが多いので、言語によっては多次元配列自体をあまり使用しないほうがいいでんでしょうかね。。。。
もしコードのミスに気付いた方や、もっといい書き方あるよ~というのがあればコメントで教えていただけると幸いです。