У меня есть страница, на которой отображаются два объекта, а затем пользователь выбирает один из них. Я записываю предпочтение и комбинацию в базу данных MSSQL и в итоге сохраняю данные следующим образом:
UserId=1, BetterObjectId=1, WorseObjectId=2
Теперь я бы хотел больше не показывать эту комбинацию объектов (1,2 / 2,1).
Итак, как мне генерировать случайные комбинации, чтобы показать пользователю исключая ранее просмотренные комбинации?
Кажется, это должен быть очень простой вопрос, но, как и большинство программистов, мне не хватает сна и кофе, поэтому ваша помощь очень ценится: -)
Очень наивный подход очень подобен этому (и все вызовы этой функции должны быть обернуты в проверку, чтобы увидеть, оценивал ли пользователь уже столько раз, сколько nCr, где n - элемент число и г 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) состоит в том, чтобы сгенерировать все возможные комбинации и сохранить код комбинации в рейтинге. Затем я могу просто выполнить ВЫБОР всех комбинаций, ГДЕ комбинационного идентификатора нет (ВЫБРАТЬ комбинацию идентификаторов из рейтингов, ГДЕ userId = x) с некоторыми изменениями, чтобы отразить симметричное соотношение комбинаций.