I have a page that displays two objects, and then the user selects one of them. I write preference and combination in the MSSQL database and end up storing the data as follows:
UserId=1, BetterObjectId=1, WorseObjectId=2
Now I would like to no longer show this combination of objects (1.2 / 2.1).
So, how do I create random combinations to show the user, excluding previously viewed combinations?
It seems that this should be a very simple question, but, like most programmers, I canβt sleep and coffee, so your help is much appreciated :-)
The naive approach is very much something like this (and all calls to this function should be wrapped to check to see if the user has already rated as many times as nCr, where n is item count and r is 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) { i = null; i2 = null; } } return r; } private List<Item> GetTwoRandomItemsRaw() { return Items.ToList().OrderBy(i => Guid.NewGuid()).Take(2).ToList(); }
edits
Using some SQL, I can generate a list of all elements that are not complete (i.e. there is a combination with an element that the user has not seen), but I do not think this is particularly useful.
I can also imagine how to create any possible combination and exclude already viewed before choosing 2 random elements, but this is another scary decision.
Opportunity (intensive memory for large n) - generate all possible combinations and save the combination in the rating. Then I can just do a SELECT of all the combinations. WHERE combinationId IS NOT IN (SELECT combId FROM ratings WHERE userId = x) with some changes that reflect the symmetrical ratio of the combinations.