PHPには'shuffle'というその名の通り配列をシャッフルしてくれる関数がある。
例えば以下のようなコードがあったとしたら
<?php $numbers = range(1, 5); shuffle($numbers); print_r($numbers); ?>
こんな感じでシャッフルされる
Array ( [0] => 2 [1] => 4 [2] => 5 [3] => 3 [4] => 1 )
たまにこういった処理が必要になるが他の言語ではどうすればいいか?
どの言語でも
10 * 3
という式を評価するとたいていは
30
という数値が得られる。
単純に10という数値に3を掛けた結果だ。
この'*'という演算子はRubyやPythonでは文字列に対しても適用できる。
例えば
Perlにはスカラーコンテキスト、リストコンテキスト(他にもブール値コンテキスト、無効コンテキスト等々)という概念があるが、これらのおかげで柔軟なコーディングをすることが出来るようになる。
例えば"localtime"という関数は単純に日時を返してくれる関数だが
プログラムを書いてるとき実験用のデータとして人物名が何人分か欲しいとする。
こういった事は結構あるだろう。
この場合一人一人それらしい名前を考えるのも意外と面倒だったりする。
ましてや数十人分欲しいとなると名前を考えるだけで一苦労だ。
こんなとき、例えば3人分の名字、3人分の名前をすべて組み合わせて9人分の架空人物名を作る事が出来る。
Perlの配列は以下のように宣言できる
my @Animals = qw/Dog Rat Rabbit Horse Cat Elephant/;
その後
my @a = @Animals;
とすれば変数@aには全く同じ値が格納されている。
ではこうしたらどうなるだろう?
PHPには可変関数というものがあるが、これは変数に格納された文字列を関数名として展開してくれる機能だ。
これを使用すれば、後から文字列を使って関数を呼び出せる事になる。
例えば
PerlやPHPでは文字列を連結する時と数値を足す時では演算子が違うので例えば
$num1 = 10; $num2 = 20; print $num1 . $num2."\n"; print $num1 + $num2."\n";
上の例ではそれぞれ
1020 30
と出力される。
では数値と文字列に対してそれぞれの演算子を適用してみる。
いろいろなプログラム言語があるがたいていどの言語もファイルを開いて読み書きする操作(関数やメソッド)が用意されている。
openと付く関数名が多いようだ。例えばPerlの場合は
前回のエントリーではPythonを使い、辞書の値でソートする方法について書いたが同様の事を他の言語でやりたい時はどうすればいいか?
例によって名前と年齢のハッシュがあったとする。例えばPerlの場合、
my %smap = ('nakai' => 36, 'kimura' => 35, 'katori' => 31, 'kusanagi' => 34, 'inagaki' => 34);
こんなデータがあり、これを年齢でソートしてみる。
ざっとこんな感じだ。
Pythonのデータに辞書という型があるが、これは他の言語でいうハッシュや連想配列と思って大丈夫だろう。
言語によって違いはあるが普通に
uniform_number = { 'Hisanori': 21, 'Tatsunori': 88, 'Greisinger': 29, 'Takuya': 0 }
などとして
print uniform_number['Hisanori']
とすれば
21
と出力される。
リスト(配列等)の内容を元に別の内容に変換したリストが欲しい時map関数(メソッド)が使える。
まずは簡単なサンプルを
普段Macを使って作業をしているが、ちょっとしたプログラムを書いてテストするときはよくデスクトップに保存してからターミナルを起動する。chmod +xとして該当のプログラムファイルをドラッグし、実行の属性を与え、もう一度そのファイルをドラッグして実行。
テストプログラムを書く時はこれの繰り返しだ。
Rubyだと以下のような文が書ける
list1 = %w/taro hanako ryota hiroshi kotaro haruki kiyotaka jun/ list2 = list1.sort
これはlist1の配列を並べ替えた新規の配列list2を作成している。
list1は元の順番のまま何の変更も加えられていない。
さらに以下のような文も書ける
list1 = %w/taro hanako ryota hiroshi kotaro haruki kiyotaka jun/ list2 = list1.sort!
上の文との違いはsortの後ろに感嘆符(!)が付いているかいないかだけだが感嘆符がついた方はlist1自身を並べ替えてしまう。
つまりはlist1とlist2は同じ順番で並んだ全く同じ配列となる。
下のコードが何をしているか理解できるだろうか?
#!/opt/local/bin/perl use strict; use warnings; my @name1 = qw/yuta kenta koz ichiro masato manabu aiko/; my @name2 = qw/hiroshi motoo koz takeshi makoto manabu/; my %union = (); my %intersection = (); $union{$_}++ && $intersection{$_}++ for (@name1, @name2); my @union = keys %union; my @intersection = keys %intersection;
前回のエントリーで値を返す返さないとかいう事を書いたが、それが1番分かりやすいのがインタラクティブシェルだ。
Pythonの場合は引数なしで起動、Rubyはirbでそれぞれインタラクティブシェルが使える。
プログラミングを学び始めた頃は当然分からないことだらけで多分本を読んでも理解できない事の方が圧倒的に多い。
"式が値を返す"というのも最初は何の事だかいまいちピンとこなかった。
"関数が値を返す"というのは何となく分かりやすい、関数定義の中で
sub { my $name = shift; return $name; }
とすれば名前が返ってくるんだなと。
たとえば配列が2つ有って、その中で重複する値を知りたいとする。
片方は別に配列でなくてもいいのだが(ディレクトリハンドルが読み出すファイルのリスト等でもいい)要はその値が他方の配列の中に存在するかどうかを知りたいというのはよくある。
例えばRubyだとinclude?というメソッドがあるしPythonの場合in演算子というのが使える。
それぞれコードは