私はデータベースからレコードの配列を持っています(データベースはこの質問と無関係ですが、最終的には
“行”の配列になり、各行はフィールド名に対応する文字列キーを持つ配列です)。例えば:
$items = array(
1 => array('id' => 1, 'name' => 'John', 'created' => '2011-08-14 8:47:39'),
2 => array('id' => 2, 'name' => 'Mike', 'created' => '2011-08-30 16:00:12'),
3 => array('id' => 5, 'name' => 'Jane', 'created' => '2011-09-12 2:30:00'),
4 => array('id' => 7, 'name' => 'Mary', 'created' => '2011-09-14 1:18:40'),
5 => array('id' => 16, 'name' => 'Steve', 'created' => '2011-09-14 3:10:30'),
//etc...
);
私がしたいことは、この配列をシャッフルすることですが、最近の「作成済み」タイムスタンプを持つアイテムに何らかの
“重み”を与えます。ランダム性は完璧である必要はなく、正確な重量は本当に私にとって重要ではありません。言い換えれば、ちょっとしたものが人にランダムに見えるが、数学的にランダムではない、素早く簡単なテクニックがあれば、私はそれで大丈夫です。また、これがタイムスタンプの「無限連続体」で行うのが容易でない場合は、各レコードを1日または1週間に割り当てて、その日または週に基づいて重み付けを行うだけでよい。
このランダム化は私のウェブサイトの特定のページのすべてのページロードで発生するので、比較的高速で効率的な手法が望ましいです(ただし、効率的に行うことができない場合は、定期的に実行して結果をキャッシュするのは大丈夫です)。
ベストアンサー
例えば、あなたは使うことができます。この比較関数:
function cmp($a, $b){
$share_of_a = $a['id'];
$share_of_b = $b['id'];
return rand(0, ($share_of_a+$share_of_b)) > $share_of_a ? 1 : -1;
}
次のように使用します。
usort($items, 'cmp');
IDに基づいた配列の2つの要素を比較します(作成日に基づいて割り当てられます。新しい要素のIDが大きくなります)。比較は無作為に行われ、各要素の成功の可能性が異なり、より新しい要素にチャンスが与えられます。
ID(新しい要素)が大きいほど、最初に表示される可能性が高くなります。
たとえば、 id = 16
の要素は、結果のリストの前に id = 1
要素よりも多くのチャンスがあります。