Using C#/Asp.Net.
I'm trying to achieve the following:
I have a list of price quotes - sometimes there are multiple products with the same price.
Also, some of the results are affiliated (sponsored), so we need to give a preference to those too.
Here's the method that is called:
public IEnumerable<PriceQuote> BestQuote(int take = 0) { var q = Quotes.Where(x => x.TotalRepayable == MinPrice) .Shuffle() .OrderByDescending(x => x.ProductDetail.Product.IsSponsored); return take == 0 ? q : q.Take(take); } The code selects items that have the lowest available price. The idea is then to sort them into a completely random order, then sort again by the sponsored flag descending (sponsored = 1 as opposed to 0), then take however many results are required.
I first shuffle them to get a random order - from the random list I want to take the sponsored items first - then if necessary fill the spaces with non sponsored items. The theory is that both sponsored and non-sponsored will be in a random order each time.
Example in natural order: product1 (not sponsored) product2 (sponsored) product3 (not sponsored) product4 (sponsored) product5 (not sponsored) product6 (sponsored) Shuffle randomly: product3 (not sponsored) product1 (not sponsored) product2 (sponsored) product6 (sponsored) product5 (not sponsored) product4 (sponsored) Order by sponsored first keeping randomness: product2 (sponsored) <-- pick these first product6 (sponsored) product4 (sponsored) product3 (not sponsored) product1 (not sponsored) product5 (not sponsored) Here's my Shuffle method:
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> @this) { if (@this.Count() <= 1) return @this; return @this.ShuffleIterator(new Random()); } static IEnumerable<T> ShuffleIterator<T>(this IEnumerable<T> source, Random rng) { var buffer = source.ToList(); for (int i = 0; i < buffer.Count; i++) { int j = rng.Next(i, buffer.Count); yield return buffer[j]; buffer[j] = buffer[i]; } } The issue I have is that when I call the BestQuote method a number of times in succession for different quotes, I tend to get the same results returned. For instance, my list contains 6 products and I make 3 calls selecting the first result each time, chances are that the order is the same for all 3 calls. It' is not always the case - there are some variances, but there are more matches than non matches.
Call 1: product2 <-- Call 2: product2 <-- Call 3: product2 <-- this is a common scenario where there seems to be no randomness
new Random()uses the current time as seed, and if you instantiate those close together, you get the same time = same seed = same values.rng.Next(int.MaxValue)%buffer.Count