Search code examples
c#linqlinq-to-entities

Order list "randomly" per day


I have an IQueryable<Post> and to sort it randomly I do the following:

IQueryable<Post> posts = getPosts();

posts = posts.OrderBy(x => Guid.NewGuid());

Is it possible to sort it randomly but for each day?

If I order it on 18 of April I would always get the same order.

But on 19 of April I would get another random order.


Solution

  • Guids are not guaranteed to be random, only unique. Do not use Guids for random data. There are specific classes in the .NET framework designed to give (pseudo) random numbers - Random is the easiest one, but if you want crypographical quality try System.Security.Cryptography.RandomNumberGenerator.

    In your case Random is your friend. You can seed it with a value created from today's date.

    Try this:

    var seed = (int)DateTime.Now.Date.Ticks;
    var random = new Random(seed);
    
    IQueryable<Post> posts = getPosts();
    
    Post[] sorted =
        posts
            .ToArray()
            .Select(post => new { post, random = random.Next() })
            .OrderBy(x => x.random)
            .Select(x => x.post)
            .ToArray();
    

    When I run that with the harness code:

    IQueryable<Post> getPosts()
    {
        return Enumerable.Range(0, 5).Select(x => new Post() { Id = x }).AsQueryable();
    }
    
    public class Post
    {
        public int Id;  
    }
    

    I get 4, 3, 1, 0, 2 today. Tomorrow it will be 4, 2, 3, 0, 1. And Tuesday it will be 3, 4, 2, 0, 1.