PHPには'shuffle'というその名の通り配列をシャッフルしてくれる関数がある。
例えば以下のようなコードがあったとしたら
<?php $numbers = range(1, 5); shuffle($numbers); print_r($numbers); ?>
こんな感じでシャッフルされる
Array ( [0] => 2 [1] => 4 [2] => 5 [3] => 3 [4] => 1 )
たまにこういった処理が必要になるが他の言語ではどうすればいいか?
Rubyにはデータを出力するためのメソッドに
print puts p pp(require 'pp'が必要)
と、たくさんあるが、'p'や'pp'は主にデバッグ用のメソッドで実際のプログラムで使用するのはあまり行儀のいいことではないとされている。
どの言語でも
10 * 3
という式を評価するとたいていは
30
という数値が得られる。
単純に10という数値に3を掛けた結果だ。
この'*'という演算子はRubyやPythonでは文字列に対しても適用できる。
例えば
Rubyの配列'Array'には"each_with_index"という便利なメソッドがある。
実際はArrayクラスに実装されているわけではなくArrayクラスがインクルードしている'Enumerable'モジュールで実装されている。
以前、railsでちょっとした日記みたいな物を作った事があるがこの時に'active_record'や'active_support'が非常に便利だと分かった。
なのでrails以外でちょっとしたWebアプリを作るときなんかもこれが使えると便利だなあ・・と思っていたんだが。
なかなか思うようにはいかなかった。具体的にはrbxやrhtmlのファイルの中で
require "rubygems" require "active_record"
こうすると"Internal Server Error"になってしまうのだ。
その後あーしたりこーしたりいろいろとやってみたのだが、結局うまくいかず自分の中では出来ないものとなっていたんだが、Webを調べていくうちに解決方法が分かった。
久々に会社で使っているMacProを初期化してみた。
まずはOS10.5のクリーンインストール。
その後ソフトウェアアップデートをかけ、終わったらAppleのサイトからxcodeのイメージファイルをダウンロードしてインストール。
そしてmacportsのサイトからLeopard用のイメージファイルをダウンロードしてインストールする。
ここまではそれほど時間はかからないがこっからがちょっと長い。
プログラムを書いてるとき実験用のデータとして人物名が何人分か欲しいとする。
こういった事は結構あるだろう。
この場合一人一人それらしい名前を考えるのも意外と面倒だったりする。
ましてや数十人分欲しいとなると名前を考えるだけで一苦労だ。
こんなとき、例えば3人分の名字、3人分の名前をすべて組み合わせて9人分の架空人物名を作る事が出来る。
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
と出力される。
Rubyを使って簡単なクラスを定義してみる。
class Person attr_reader :name def initialize(name) @name = name end end
前回のエントリーでmap関数(mapメソッド,map演算子)について書いているが、書いているうちにいろいろと気づく事があった。
たとえばRubyのコード
#!/usr/bin/env ruby Dir.chdir File.dirname(ENV["_"]) Dir.open(".") do |dir| fileAndSize = dir.select {|i| i =~ /^[^.]/}.map {|i| [i, FileTest.size(i)]} fileAndSize.each {|l| puts "#{l[0]} => #{l[1]}byte"} end
では、まずEnumerableモジュールのselectメソッドを呼び出しリストの内容をふるいにかけた後mapメソッドで変換の作業をしている。
次の部分だ。
リスト(配列等)の内容を元に別の内容に変換したリストが欲しい時map関数(メソッド)が使える。
まずは簡単なサンプルを
Pythonの変数はリファレンスという仕組みを使っている。
例えば
a = 1 b = 1
という代入文があったとしたら、これは変数aもbもおなじオブジェクト(数値の1)を参照しているという事だ。
なので
id(a) id(b)
を実行してみるとそれぞれ同じIDが出力されるはずだ。
その後
b = 2
とすれば変数bはオブジェクト(数値の2)を参照することになり
id(a) id(b)
を見てみるとここでは違ったIDが出力される。
では
a = 1 b = a
とした場合はどうだろうか?
普段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は同じ順番で並んだ全く同じ配列となる。
プログラミングを学び始めた頃は当然分からないことだらけで多分本を読んでも理解できない事の方が圧倒的に多い。
"式が値を返す"というのも最初は何の事だかいまいちピンとこなかった。
"関数が値を返す"というのは何となく分かりやすい、関数定義の中で
sub { my $name = shift; return $name; }
とすれば名前が返ってくるんだなと。