配列からユニークな要素をランダムに取り出す

投稿日:

「うわ〜。やっぱりPHPは偉いなぁ!」

と非常に感心したので、メモ。

ふと思いついて、このサイトのトップページに「検索語の一覧」みたいのを出そうと思いたちました。検索語自体は既に別の用途で抽出してるので、あまり手間が要らなさそうだし。

ワタシはperlのスキルがまるでない(他の事もかなり怪しい(^^;;)のでMTのプラグインとして実装したりするのはまるで無理→スタンドアロンのPHPスクリプトとして実装を試みます。

とりあえず、検索語をバラして配列にぶっ込みます。検索語に全角空白や改行記号等が含まれてると都合が悪いんで、全角空白を半角空白に置換し、改行を抹殺して配列に入れます。

$i = 0;

while (list($num, $line) = each($page)){

//タグを抹殺&全角空白を半角化
//表現ゆらぎを低減するため小文字&半角化
//半角空白で文字列を分解して配列に格納
$pieces = explode(" ", strtolower(mb_convert_kana(strip_tags($line), "saKV")));

$l = 0; //ローカルカウンタ

do {
//要らん空白と改行を抹殺してから部品を再度配列へ格納
$input[$i] = ereg_replace("\n|\r|\r\n"," ",trim($pieces[$l]));
$i++;
$l++; //ローカル/グローバルの両カウンタをインクリメント

} while($pieces[$l] != ""); //部品が無くなるまでループ

}

本来なら組みになってる語もバラして単語単位で配列に入れちゃった→配列内の要素がかなりダブっちゃってさぁどうしようかと思ってたトコロ、PHPにはちゃんと配列をユニークにしてくれる関数があるということを発見!

array_unique

array_unique() は、 arrayを入力とし、値に重複のない新規配列を 返します。

うわ、素晴しい!! つまり、

//重複した部品を消す
$result = array_unique ($input);

↑このたった1行で、重複語句が消えて無くなってくれた訳です。自分でループを回していちいちチェックするのに比べ、なんと効率の良い事か。PHPはCに似てますが、こんな便利な関数が一杯有って格段に使い易いです(^_^)

ということはもしかして…と探すと、やっぱりありました。

shuffle

この関数は、(要素の順番をランダムにするために)配列をシャッフルし ます。この関数にシードを与えるためにsrand()を 使用する必要があります。

ということで

//配列をシャッフル
srand ((float)microtime()*1000000);
shuffle ($result);

配列のランダム化は↑この2行で終わりまして、

fwrite($fp,"<div class=\"side\">\n");

$i=0; //カウンタの初期化
$limit=8; //出力したい語句数

//もし総検索語数が出力語句数よりも小さければ
//出力語句数を総検索語数とする
$count = count($result) - 1;
if ($count < $limit) $limit = $count;

do {

//array_uniqueで配列を処理すると空き配列が出来る場合が
//あるので、中身の有無を確認
if ($result[$i] != "") {

fwrite($fp,"<a href=\"https://crusherfactory.net/~yas_/mt/mt-search.cgi?search=");
//検索語はurlエンコードして引数に
fwrite($fp,urlencode($result[$i]) . "\"");
fwrite($fp," title=\"このサイトで『" . $result[$i] . "』を検索する\">");
fwrite($fp,$result[$i]);
fwrite($fp,"</a>");

$i++; //中身があれば出力後カウンタをインクリメント

//最後の単語かどうかを判別
if ($i != $limit) {

fwrite($fp," / \n"); //最後じゃないなら区切りを出力

}else {

fwrite($fp,"\n"); //最後なら区切りを出さない

}

} while($i < $limit); //出力したい語句数までループ

fwrite($fp,"</div>\n");

あとは出力部分の形式を整えてやるだけで、実に簡単に「全検索語からランダムに単語を取り出す」プログラムが書けちゃいました。スゴイ!(^_^)