ワテの場合、PHPは初心者だ。
配列を使う場面で少し混乱したのでその備忘録。
PHPで配列変数をどうやって使うのかをググったらPHP公式サイトの説明が見つかった。
引用すると以下の通り。
<?php $arr = array( "foo" => "bar", "bar" => "foo", ); // PHP 5.4 ではこのようにも書けます $arr = [ "foo" => "bar", "bar" => "foo", ]; ?>
引用元 http://php.net/manual/ja/language.types.array.php
ん?
何だかややこしいぞ。(ちなみに↑の公式サイトの例では変数名にも $array を使っているのだが、それは配列定義の array と同じなので、益々混乱する。公式サイトがそんな紛らわしい例を載せるのはおかしいだろう。なのでここでは変数名は $arr に変えた)
二通りの書き方が出来るのか。
まあ、ワテの場合には後者のカギカッコ[]を使う方式が好みだな。上図と同じだが、その部分を取り出してみた。
<?php $arr = [ "foo" => "bar", // Key => Value "bar" => "foo", // Key => Value ]; ?>
これはJavaScriptなどの連想配列と言う奴やな。 KeyとValueで定義する配列。C/C++ならmapと言う奴か。
つまりまあ、このように定義したPHPの配列変数
$arr
から特定の値を取り出したい場合には
echo $arr['foo'];
とすれば
bar
と表示される。
さて、幾つかの疑問がある。
- 0, 1 ,2 , … のようなインデックス式の配列を定義する事は出来ないのか?
- 連想配列で定義した場合でもインデックスでアクセス出来るのか?
これらの手法が使えないと何かと不便なので早速猛烈に調査してみた。
以下、その調査結果。
インデックス式の配列を定義する事は出来ないのか?
ワテの調査の結果、PHPの配列は上記の説明の通り連想配列になるので、必ず Key, Value のペアの形式になる。
つまり、C#、C、C++、JavaScript などの他の言語で一般的な値だけからなる配列を定義する事は出来ないようだ。
しかしながら、配列を定義する場合にKeyを省略する事が可能である(下図)。
$arr1 = Array('東京', '大阪', '京都'); // これでも配列は定義出来るし $arr2 = ['東京', '大阪', '京都']; // これでも配列は定義出来る(ワテ好み)
このようにKey無しでValueのみ与えてPHPの配列を定義する。
それで配列変数の中身を出力してみる。
print_r($arr2); // 配列変数の中身を表示する
以下のように出力される。
Array ( [0] => 東京 [1] => 大阪 [2] => 京都 ) // 表示結果
つまり、Keyを指定せずにPHPの配列変数を定義すると、自動的に整数値 0, 1, 2, … と言う連番がKeyに割り当てられるのだ。
おお、これは便利。
echo $arr2[0]; // 東京 と表示される。printでも良い。
Keyは自動で追加されるが、必要なければ使わなければ良い。値のValueだけを使えばいいのだ。
では、実際に配列をループ処理する場面を想定して、幾つかの手法を調査した。
PHP配列のループ処理
Valueのみ取り出す
もし、この配列変数をループで処理したい場合には、
<?php $arr = ['東京', '大阪', '京都']; foreach ($arr as $value) { echo $value; } ?>
PHPでforeachループを使う例
とすると配列arrの要素を取り出せる。
Keyは使わずに、Valueのみを使っている。
KeyとValueを取り出す
あるいは、自動的に追加されたKeyも取り出したい場合には、
<?php $arr = ['東京', '大阪', '京都']; foreach ($arr as $key => $value) { echo $key.':'.$value.'<br/>'; // $key=0, 1, 2, .. } ?>
とすれば、
0:東京 1:大阪 2:京都
となる。
この例では自動的に追加されたKeyが表示されるが、この方式は一般的なPHP配列にも当然使えるので、その場合には自分で設定した Key と Value が出力される。
連想配列にインデックスでアクセス出来るのか?
IndexでValueを取り出す
やはり配列変数にはインデックス方式でアクセスできるほうが便利である。
<?php $arr = ['東京', '大阪', '京都']; for ($i=0;$i< count($arr);$i++) { echo $i.':'.$arr[$i].'<br/>'; } ?>
これで行ける。インデックスを使うメリットは、ワテの場合には今何番目の要素を処理しているのか分るので安心感がある。
では、最後に、3つの値(KeyとValueとIndex)の全部をループの中で利用したい場合の処理だ。
KeyとValueとIndexを取り出す
<?php $arr = ['Tokyo'=>'東京', 'Osaka'=>'大阪', 'Kyoto'=>'京都']; $keys = array_keys($arr); // ループの前にKeyのみの配列を作成する for ($i=0;$i< count($arr);$i++) { $key_i = $keys[$i]; echo $i.':'.$key_i.':'.$arr[$key_i].'<br/>'; } ?>
ここでは $keys は
[0] => 'Tokyo', [1] => 'Osaka', [2] => 'Kyoto',
と言う配列になる。
後は上図のように、ループのインデックス変数 $i を使って $key_i = $keys[$i] キーを取り出し、そのキーを使って値 $arr[$key_i] を取り出している。
Key, Value型の配列から、Valueのみ取り出した配列を作成したい場合
では、Key, Value型の配列から、Valueのみ取り出した配列を作成したい場合はどうするか?
つまり、下図のようなKey, Value型の配列 $arrKV があるのだが、
<?php $arrKV = [ "Tokyo" => "東京", "Osaka" => "大阪", "Kyoto" => "京都", ]; ?>
Keyの文字列データは不要なので、整数のインデックス 0, 1, 2, … を持つ配列を作成したい(下図)。
<?php $arr = [ 0 => "東京", 1 => "大阪", 2 => "京都", ]; ?>
つまりこれは、PHP配列宣言でKeyを省略した場合に生成される配列だ。
<?php $arr = ["東京", "大阪", "京都" ]; ?>
array_values() 関数も便利
さて、$arrKV から $arr を生成する関数もPHPにはあった。
下図のように array_values() 関数を使うと良い。
<?php $arr = array_values($arrKV); ?>
その結果、 $arr はKey に 0, 1, 2, … を持つのでIndex方式で扱いやすくなる。
つまり、
echo $arr[0]; // 東京 echo $arr[1]; // 大阪 echo $arr[2]; // 京都
のように扱える。
じゃあ、Keyを持つ配列とValueを持つ配列を合体させてKeyValue配列を作るにはどうするか?
Key配列とValue配列を合体させてKeyValue配列を作る
まあ、どういう状況でそんな必要があるのか分からないが、例えばこんな状況だ。
$keys = ['Tokyo', 'Osaka', 'Kyoto']; $vals = ['東京', '大阪', '京都']; $arr = array_combine($keys, $vals); var_dump($arr);
$keys と $vals は、Keyを省略して定義しているので、共に Key=0, 1, 2, … を持つ配列だ。
そう言う2つの配列を合体させて、以下のような配列にしたい。
$arr = [ "Tokyo" => "東京", "Osaka" => "大阪", "Kyoto" => "京都", ];
array_combine() と言う関数を使うと出来る。
まあ、PHPには配列の操作に関して色んな関数があるようだ。
まだまだ他にも沢山有るのかも知れない。
と言う事で、PHP初心者のワテが
- PHPの配列変数の定義のしかた、
- forループで配列を扱う場合の各種の手法、
を調査した。
以下、余談であるが、PHPの配列やループを調査していて気になった点をまとめてみた。
C、C++、C# の経験の長いワテにはちょっと混乱する点も多いのでその備忘録。
PHPのforeachのパラメータの並びがC#とは逆
C#のforeachの value と arr の並びの順(下図)とPHPのforeach の value と arr の並びの順が逆なのだ。まあ、慣れてしまうと問題は無いが。
class Program { static void Main(string[] args) { var arr = new string[] { "東京", "大阪", "京都" }; foreach (var value in arr) // valueとarrの順番がPHPと逆転している { Console.WriteLine(value); } } }
コード C#でforeachループを使う例
でもなあ、foreachのパラメータの並びはC#のほうが普通だと思うのだが、まあ、そんな事はどうでも良い。
PHP配列のループ処理中に配列変数の中身を変更する場合
ちなみに、ループ処理中に配列変数の値を変更する事も可能だ。
<?php
$arr = ['東京', '大阪', '京都'];
foreach ($arr as &$value) {
$value = $value.'都';
}
// $arr は ['東京都', '大阪都', '京都都']
unset($value); // 最後の要素への参照を解除する
?>
上図のようにループ変数 $value の頭に参照を意味する & を付けるのが味噌だ。
まあ、C/C++のforループ内で参照の & を使うようなもんか。
#include <iostream> using namespace std; #include <string> #include <vector> int _tmain(int argc, _TCHAR* argv[]) { setlocale(LC_ALL, "Japanese"); std::vector<std::wstring> vect = { L"東京", L"大阪", L"京都" }; for (auto &x : vect) { std::wcout << x << std::endl; x = x + L"府"; std::wcout << x << std::endl; } }
コード C++でvector要素をforループでアクセスする例
この&を付けておくと、ループの中でvectの中身を変更する事が出来て、脱出後に確認すると “府” が追加されている。
久しぶりにC++のコードをVisual Studio 2015 Communityを使って書いたら、日本語の扱いをすっかり忘れていた。
ロケール設定のsetlocaleを入れて、stringではなくてwstringを使い、出力も coutではなくて wcoutを使い、文字定数には頭に L を付ける。これで日本語を正しく扱う事が可能だ。
さて、PHPを勉強中の人にはC#やC++の話題は興味が無いかも知れないので、これくらいにして、本題に戻ろう。
まとめ
疲れた。
今日はこれくらいにしといたろ。
アマゾンランキングも高いので人気あるようだ。
PHPをやるならMySQLなどのデータベースの操作をしたい。
PHPとMySQLを組み合わせるのはサーバーサイドプログラミングの醍醐味と言う奴だな。
最近ワテも PHP+MySQL にはまっている。
なお PHP+ SQL Server Express もそれ用の拡張機能をインストールすれば出来るようなので、今後挑戦したい。
コメント