2 つのオブジェクトを表示するページがあり、ユーザーはそのうちの 1 つを選択します。好みと組み合わせを MSSQL データベースに記録し、最終的に次のようなデータを保存します。
UserId=1, BetterObjectId=1, WorseObjectId=2
ここで、オブジェクトの組み合わせ (1,2 / 2,1) を二度と表示したくありません。
では、ランダムな組み合わせを生成して、以前に表示した組み合わせを除外してユーザーに表示するにはどうすればよいでしょうか?
これは本当に簡単な質問のように思えますが、ほとんどのプログラマーと同じように、私は睡眠とコーヒーが不足しているので、あなたの助けに感謝します:-)
非常に単純なアプローチは次のようなものです (この関数へのすべての呼び出しは、ユーザーが既に nCr (n はアイテム数、r は 2) と同じ回数評価しているかどうかを確認するためにチェックでラップする必要があります):
public List<Item> GetTwoRandomItems(int userId)
{
Item i = null, i2 = null;
List<Item> r = null;
while (i == null || i2 == null)
{
r = GetTwoRandomItemsRaw();
i = r[0];
i2 = r[1];
if (GetRating(i.Id, i2.Id, userId) != null) /* Checks if viewed */
{
i = null;
i2 = null;
}
}
return r;
}
private List<Item> GetTwoRandomItemsRaw()
{
return Items.ToList().OrderBy(i => Guid.NewGuid()).Take(2).ToList();
}
編集
一部の SQL を使用して、完全ではないすべてのアイテムのリストを生成できます (つまり、ユーザーが見たことのないアイテムを含む組み合わせがあります) が、特に役立つとは思いません。
2 つのランダムな項目を選択する前に、すべての可能な組み合わせを生成し、既に表示されているものを削除することも想像できますが、これは別のひどい解決策です。
1 つの可能性 (大きな n に対してメモリを大量に消費する) は、考えられるすべての組み合わせを生成し、combinationId を評価に格納することです。次に、組み合わせの対称関係を反映するためにいくつかの変更を加えて、すべての組み合わせの SELECT を行うことができます。