【PHP 初級】配列を使いこなす➀ ~宣言・初期化・追加・結合・削除~の続きです。
今回は配列から値を取得、検索する方法など、もう少し実務的な内容をまとめます。
値の取得
配列から値を取り出す色んな方法を見てみます。
キーを指定して値を取り出す
どの言語も同じように、数値やキーを指定して値を取り出します。
php>$fruits=['apple','grape','banana'];php>var_export($fruits[0]);'apple'
php>$colors=['C1'=>'red','C2'=>'purple','C3'=>'green'];php>var_export($colors['C1']);'red'
すべての値を取り出す
array_values
https://www.php.net/manual/ja/function.array-values.php
array_values (配列)
戻り値:配列
array_values
は配列のすべての値を取り出し、数値のインデックス番号を付けた配列を返します。
【PHP】配列を使いこなす➀ ~宣言・初期化・追加・結合・削除~で紹介したように、配列の値の削除を行った後、インデックス番号を詰め直すのに利用したりします。
またarray_values
に連想配列を渡せば、配列に変換することが出来ます。
php>$colors=['C1'=>'red','C2'=>'purple','C3'=>'green'];php>var_export(array_values($colors));array(0=>'red',1=>'purple',2=>'green',)
多次元配列からキーを指定して値を取り出す
array_column
https://www.php.net/manual/ja/function.array-column.php
array_column (配列, 指定するキー)
戻り値:配列
array_column
は個人的にかなり良く使うメソッドなので、ぜひ使い方を身に付けてみてください。array_column
は多次元配列のキーを指定し、全ての値を配列で返します。
php>$students=[php>['class'=>1,'name'=>'tanaka','age'=>15],php>['class'=>2,'name'=>'yamamoto','age'=>16],php>['class'=>1,'name'=>'honda','age'=>16],php>['class'=>3,'name'=>'inoue','age'=>17],php>];// 学生の名前を取得php>$students_name=array_column($students,'name');php>var_export($students_name);array(0=>'tanaka',1=>'yamamoto',2=>'honda',3=>'inoue',)
また第3引数を指定して、特定の値をキーにした多次元配列を生成することもできます。
array_column (配列, 指定するキー、新しい配列のキーとして指定するキー)
戻り値:配列
言葉が分かりづらいですが、例を見ればすぐに理解できると思います。
php>$students=[php>['class'=>1,'name'=>'tanaka','age'=>15],php>['class'=>2,'name'=>'yamamoto','age'=>16],php>['class'=>1,'name'=>'honda','age'=>16],php>['class'=>3,'name'=>'inoue','age'=>17],php>];// クラス毎に名前を取得するphp>$name_by_class=array_column($students,'name','class');php>var_export($name_by_class);array(1=>'honda',2=>'yamamoto',3=>'inoue',)
注意点はキーが重複する場合、後ろの値で上書きされます。
そのため、クラス1はhondaくんが取得されます。
名前だけでなく、学生の情報が全て取得したい場合は第2引数にnull
を指定します。
php>$students=[php>['class'=>1,'name'=>'tanaka','age'=>15],php>['class'=>2,'name'=>'yamamoto','age'=>16],php>['class'=>1,'name'=>'honda','age'=>16],php>['class'=>3,'name'=>'inoue','age'=>17],php>];// クラス毎に学生の情報を取得するphp>$student_by_class=array_column($students,null,'class');php>var_export($student_by_class);array(1=>array('class'=>1,'name'=>'honda','age'=>16,),2=>array('class'=>2,'name'=>'yamamoto','age'=>16,),3=>array('class'=>3,'name'=>'inoue','age'=>17,),)
こちらもクラス1は重複するため、hondaくんの情報のみ取得されています。
多次元配列のキーでグルーピングする
上書きしないでクラス毎の全員の情報が取得したい場合は、次のような自作メソッドが必要になります。
publicfunctiongroupBy($list,$key){$ret=array();if(is_array($list)){foreach($listas$val){$ret[$val[$key]][]=$val;}}return$ret;}
Utilメソッドとして定義し、どこからでも使えるようにしたら良いです。
グルーピングした結果は以下のようになります。
php>$students=[php>['class'=>1,'name'=>'tanaka','age'=>15],php>['class'=>2,'name'=>'yamamoto','age'=>16],php>['class'=>1,'name'=>'honda','age'=>16],php>['class'=>3,'name'=>'inoue','age'=>17],php>];// クラス毎に学生をグループ化するphp>$group_by_class=groupBy($students,'class');php>var_export($group_by_class);array(1=>array(0=>array('class'=>1,'name'=>'tanaka','age'=>15,),1=>array('class'=>1,'name'=>'honda','age'=>16,),),2=>array(0=>array('class'=>2,'name'=>'yamamoto','age'=>16,),),3=>array(0=>array('class'=>3,'name'=>'inoue','age'=>17,),),)
キーの取得
次はキーを取得する方法を見てみましょう。
配列の全てのキーを取得する
array_keys
https://www.php.net/manual/ja/function.array-keys.php
array_keys (配列)
戻り値:配列
引数に渡した配列の全てのキーを配列にて返します。
php>$fruits_color=[php>'apple'=>'red',php>'banana'=>'yellow',php>'orange'=>'orange',php>'cherry'=>'red',php>];php>var_export(array_keys($fruits_color));array(0=>'apple',1=>'banana',2=>'orange',3=>'cherry',)
値を指定してキーを取得する
array_keys
https://www.php.net/manual/ja/function.array-keys.php
array_keys (配列, 指定する値, 型比較を行うか)
戻り値:配列
指定した値に該当するキーを取得するにはarray_keys
に第2引数を渡して使用します。
第3引数には値を検索する際に厳密な比較===
を行うかどうかをtrue
,false
で指定します。
常にtrue
を指定することをお勧めします。
php>$fruits_color=[php>'apple'=>'red',php>'banana'=>'yellow',php>'orange'=>'orange',php>'cherry'=>'red',php>];php>$red_fruits=array_keys($fruits_color,'red',true);php>var_export($red_fruits);array(0=>'apple',1=>'cherry',)
もし第3引数にtrue
を指定しない場合、以下のような想定外の動作をする可能性があります。
php>$numbers=[php>'zero'=>0,php>'one'=>1,php>'two'=>2,php>];// 何も取得されないと思いきや、'zero'が取得されるphp>$number=array_keys($numbers,'a');php>var_export($number);array(0=>'zero',)
第3引数を指定しないと値の検索に緩やかな比較==
を行います。
PHPは型が異なる値同士を比較する際に、暗黙的な型変換を行います。
そのため数値と文字列を比較しようとすると、文字列は0に変換されてしまいます。
php>var_export((int)'a');0
なので上記のように第2引数に'a'を指定しても、実際には0に変換されてしまうので、'zero'が取得されてしまうのです。
このような想定外の動作はバグを引き起こす可能性があるため、避けるべきでしょう。
値の検索
値を指定して存在するか検索する
array_search
https://www.php.net/manual/ja/function.array-search.php
array_search(検索する値, 配列, 型比較を行うか)
戻り値:キーもしくはfalse
値が見つかった場合、該当のキーを返します。
見つからなかった場合はfalse
を返します。
array_keys
は値を指定した場合、該当するキーを全て配列で返しますが、array_search
は1つのキーを数値か文字列にて返します。
そのため1つ以上の値が見つかる場合は先に見つかった方のキーを返します。
php>$foods=['ramen','sushi','curry','udon','karaage','sushi'];// 寿司を検索。寿司は2つあるため、前方のキーが取得される。php>$sushi_key=array_search('sushi',$foods,true);php>var_export($sushi_key);1// ピザを検索。値が見つからないためfalseを返す。php>$pizza_key=array_search('pizza',$foods,true);php>var_export($pizza_key);false
array_search
も第3引数にtrue
を指定して厳密な比較を行うようにしましょう。
in_array
https://www.php.net/manual/ja/function.in-array.php
in_array(検索する値, 配列, 型比較を行うか)
戻り値:trueもしくはfalse
使い方はarray_search
と同じですが、値が見つかった場合にキーではなくtrue
を返します。
第3引数にはもちろんtrue
を指定します。
php>$foods=['ramen','sushi','curry','udon','karaage','sushi'];php>$sushi_key=in_array('sushi',$foods,true);php>var_export($sushi_key);truephp>$pizza_key=in_array('pizza',$foods,true);php>var_export($pizza_key);false
array_search
とin_array
の使い分けは、
値を検索して存在する場合、その値を用いて何らかの処理をしたい時はarray_search
を
$key=array_search('val',$list,true);if($key!==false){$value=$list[$key];...// 値を使って処理を行う}
値を検索して存在するかしないかで何らかの処理をしたい場合はin_array
を使うイメージです。
if(in_array('val',$list,true)){...// 存在する場合の処理}else{...// 存在しない場合の処理}
キーの検索
キーを指定して存在するか検索する
array_key_exists
https://www.php.net/manual/ja/function.array-key-exists.php
array_key_exists (検索するキー, 配列)
戻り値:trueもしくはfalse
第1引数に渡したキーが存在すればtrue
を返します。
php>$fruits=[php>'name'=>'apple','color'=>'red',php>'name'=>'banana','color'=>'yellow',php>'name'=>'melon','color'=>'green',php>];php>var_export(array_key_exists('name',$fruits));truephp>var_export(array_key_exists('price',$fruits));false
isset
やempty
を使ってもarray_key_exists
と同じようなことができます。
isset
https://www.php.net/manual/ja/function.isset.php
isset (変数)
戻り値:trueもしくはfalse
変数が宣言されていて、かつnull
でなければtrue
を返します。
php>$fruits=[php>'name'=>'apple','color'=>'red',php>'name'=>'banana','color'=>'yellow',php>'name'=>'melon','color'=>'green',php>];php>var_export(isset($fruits['name']));truephp>var_export(isset($fruits['price']));false
empty
https://www.php.net/manual/ja/function.empty.php
empty (変数)
戻り値:trueもしくはfalse
変数が宣言されていないか、空であればtrue
を返します。array_key_exist
やisset
とは逆にキーが存在しなければtrue
を返します。
同じ使い方をしたい場合は必ず!
を付けるようにしましょう。
php>$fruits=[php>'name'=>'apple','color'=>'red',php>'name'=>'banana','color'=>'yellow',php>'name'=>'melon','color'=>'green',php>];php>var_export(!empty($fruits['name']));truephp>var_export(!empty($fruits['price']));false
array_key_exists、isset、emptyの違い
array_key_exists
はキーが定義されているかどうかのみを判断します。isset
はキーが定義されているか、また値がnull
ではないかを判断します。empty
はキーが提起されているか、また値が空ではないかを判断します。
いくつかの違いをまとめると以下のようになります。
key/value | array_key_exists | isset | !empty |
---|---|---|---|
'a' => undefined | false | false | false |
0 => NULL | true | false | false |
1 => '' | true | true | false |
2 => 0 | true | true | false |
3 => 'val' | true | true | true |
// array_key_existsphp>var_export(array_key_exists('a',$list));falsephp>var_export(array_key_exists(0,$list));truephp>var_export(array_key_exists(1,$list));truephp>var_export(array_key_exists(2,$list));truephp>var_export(array_key_exists(3,$list));true// issetphp>var_export(isset($list['a']));falsephp>var_export(isset($list[0]));falsephp>var_export(isset($list[1]));truephp>var_export(isset($list[2]));truephp>var_export(isset($list[3]));true// emptyphp>var_export(!empty($list['a']));falsephp>var_export(!empty($list[0]));falsephp>var_export(!empty($list[1]));falsephp>var_export(!empty($list[2]));falsephp>var_export(!empty($list[3]));true
キーが存在するかチェックしたい場合はarray_key_exists
を、
キーが存在して意味のある値が入っていることを確認したい場合はisset
やempty
を使いましょう。
その他、配列に関する色々
JAVAのstreamぽい書き方もできる
詳細は割愛しますが、JAVAのstreamのように配列の全要素を回しながら処理する色んな関数があります。
array_walk
array_filter
array_map
など
最後の要素の後にはカンマを付ける
これは賛否両論があるようですが
・1行で記述する場合は最後にカンマを付けない
・複数行で技術する場合は最後にカンマを付ける
が一般的のようです。
配列を一行で定義する場合は、ふつうは最後のカンマを省略します。
つまり、 array(1, 2) のほうが array(1, 2, ) よりおすすめだということです。
しかし複数行で定義する場合は、最後のカンマをつけることが一般的です。
そうしておけば、配列の最後に要素を追加するのが容易になるからです。
we encourage using a trailing comma for the last item in the array; this minimizes the impact of adding new items on successive lines, and helps to ensure no parse errors occur due to a missing comma.
$sampleArray=array(1,2,3,'Zend','Studio');// 最後にカンマを付けない
$sampleArray=array(1,2,3,'Zend','Studio',$a,$b,$c,56.44,$d,500,// 最後にカンマを付ける);