我有一个显示两个对象的页面,然后用户选择其中一个。我将偏好和组合记录在 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 个随机项目之前生成所有可能的组合并消除已经查看过的组合,但这是另一个糟糕的解决方案。
一种可能性(大 n 的内存密集型)是生成所有可能的组合并将组合 ID 存储在评级中。然后我可以对所有组合进行 SELECT WHERE combinationId IS NOT IN (SELECT combinationId FROM rating WHERE userId=x) 并进行一些更改以反映组合的对称关系。