プログラムを書いてるとき実験用のデータとして人物名が何人分か欲しいとする。
こういった事は結構あるだろう。
この場合一人一人それらしい名前を考えるのも意外と面倒だったりする。
ましてや数十人分欲しいとなると名前を考えるだけで一苦労だ。
こんなとき、例えば3人分の名字、3人分の名前をすべて組み合わせて9人分の架空人物名を作る事が出来る。

まずはPHPで以下のようなコードを書いてみる。

$last_names = array("伊藤", "鈴木", "水谷");
$first_names = array("太郎", "裕次", "広志");

foreach ($last_names as $last_name) {
  foreach ($first_names as $first_name) {
    $names[] = $last_name . $first_name;
  }
}

そしてprint_rしてみると結果は。

Array
(
    [0] => 伊藤太郎
    [1] => 伊藤裕次
    [2] => 伊藤広志
    [3] => 鈴木太郎
    [4] => 鈴木裕次
    [5] => 鈴木広志
    [6] => 水谷太郎
    [7] => 水谷裕次
    [8] => 水谷広志
)

こんなデータになってるだろう。
さらにこれらのデータを例えば名字によってグルーピングした二重配列にしたい時は

foreach ($last_names as $last_name) {
  $tmp = array();
  foreach ($first_names as $first_name) {
    $tmp[] = $last_name . $first_name;
  }
  $names[] = $tmp;
}

こうすれば

Array
(
    [0] => Array
        (
            [0] => 伊藤太郎
            [1] => 伊藤裕次
            [2] => 伊藤広志
        )

    [1] => Array
        (
            [0] => 鈴木太郎
            [1] => 鈴木裕次
            [2] => 鈴木広志
        )

    [2] => Array
        (
            [0] => 水谷太郎
            [1] => 水谷裕次
            [2] => 水谷広志
        )

)

こんな構造を持った配列になる。これと同じ事を他の言語でもやってみたい。
実際、上のPHPコードはかなりオーソドックスな方法なので全く同じ考え方をそのまま適用させる事は出来る。
でもそれではつまらない、という事でもっと短く書く方法。
まずはPythonで

names = [last_name + first_name for first_name in first_names for last_name in last_names]

この1行のコードで変数namesにはPHPの時と同じデータが格納されている(フラットな配列の方)。
さらに二重配列が欲しい時は特定の箇所をブラケットで囲ってやるだけでいい。

names = [[last_name + first_name for first_name in first_names] for last_name in last_names]

これだけだ。これでPHPの時と同じ名字でグループを分けた二重配列(リスト)の出来上がりだ。

次はPerl

my @names = map {my $last_name = $_; map {$last_name . $_} @first_names} @last_names;

これがフラットな方。二重配列は

my @names = map {my $last_name = $_; [map {$last_name . $_} @first_names]} @last_names;

これでいい。

最後にRuby

names = last_names.map {|last_name| first_names.map {|first_name| last_name + first_name }}.flatten
names = last_names.map {|last_name| first_names.map {|first_name| last_name + first_name }}

上のコードがフラットな配列。下のは二重配列。

この場合は 3人分の名字 x 3人分の名前 = 9人分の氏名 という数だが。例えば10人分の名字と名前を考えれば100人分のダミーデータが出来る事になる。
20人ずつ考えれば400人分だ。

ちなみにPHPでもコードを無理矢理1行にする事は出来る。フラットな配列の時はforeachループのブロックを定義してる部分のブレースを外すだけでいい。

foreach ($last_names as $last_name) foreach ($first_names as $first_name) $names1[] = $last_name . $first_name;

二重配列の時は、ちょっと悩んだがこう書く事が出来た。

foreach ($last_names as $last_name) $names2[] = array_map(create_function('$first_name', 'global $last_name; return $last_name . $first_name;'), $first_names);

まあ、もっとうまいやり方があるかもしれないが、あまり深くは考えてない。

カテゴリ:

トラックバック(0)

トラックバックURL: http://blog.beanz-net.jp/beanz_mtos/mt-tb.cgi/29

コメントする