6

I want to write a C# program that executes several methods A(), B() and C() in random order. How can I do that?

Gjorgji
  • 22,458
  • 10
  • 31
  • 39
  • 2
    Gjorgji, the GUID idea is terrible. Please at least order by Random - or better still, use the most voted algorithm. Take the hint from those votes - the community is telling you which one is better. – Roman Starkov Jan 26 '11 at 02:04
  • a very terrible idea, which is why you won't find anything on google if you look for it http://www.google.com/search?q=orderby+%22Guid.NewGuid%22 – Pauli Østerø Jan 26 '11 at 02:30
  • 3
    @Pauli, your belief is anything that you find on Google is automatically a good idea? – Eric Lippert Jan 26 '11 at 03:13
  • @Eric: I trust everything on the Internet. –  Jan 26 '11 at 03:17
  • 1
    @Pauli, you have some serious nerves arguing your point after receiving 6 downvotes and numerous comments explaining your mistake, including two from Eric Lippert. It is becoming abundantly clear that you are not here to give right answers, nor to learn anything; you are here to bolster your ego. – Timwi Jan 26 '11 at 13:23
  • @Timwi then let me ask you this one thing. How would you write a OrderBy statement in Linq, that shuffles the returned set, that is reusable for both a IEnumerable and IQueryable source. An Expression Tree calling a method that returns a number is to no use if it will be translated into ie. ORDER BY 4 in sql. Thats not random. – Pauli Østerø Jan 26 '11 at 17:23
  • @Pauli Totally irrelevant. How would you write a OrderBy statement in Linq, that shuffles the returned set, that is reusable for both a IEnumerable and IQueryable source, and behind the IQueryable might be an OData data source? An Expression Tree calling a method that returns a number is to no use if it will be translated into ie. $orderby=guid'b0d8e6a5-b728-45a6-96e6-0f16a20e599f' in the URL. – R. Martinho Fernandes Jan 26 '11 at 19:40
  • @Pauli: ① “How would you ...” — Given the response in this thread, I wouldn’t. ② The question didn’t ask about `IQueryable`. ③ I can’t even think of a use-case where you even need that in the middle of a complex query. You can always shuffle any result set in C#. – Timwi Jan 26 '11 at 22:37

1 Answers1

15

Assuming a random number generator declared like this:

public static Random Rnd = new Random();

Let’s define a Shuffle function to bring a list into random order:

/// <summary>
/// Brings the elements of the given list into a random order
/// </summary>
/// <typeparam name="T">Type of elements in the list.</typeparam>
/// <param name="list">List to shuffle.</param>
/// <returns>The list operated on.</returns>
public static IList<T> Shuffle<T>(this IList<T> list)
{
    if (list == null)
        throw new ArgumentNullException("list");
    for (int j = list.Count; j >= 1; j--)
    {
        int item = Rnd.Next(0, j);
        if (item < j - 1)
        {
            var t = list[item];
            list[item] = list[j - 1];
            list[j - 1] = t;
        }
    }
    return list;
}

This Shuffle implementation courtesy of romkyns!

Now simply put the methods in a list, shuffle, then run them:

var list = new List<Action> { A, B, C };
list.Shuffle();
list.ForEach(method => method());
Community
  • 1
  • 1
Timwi
  • 65,159
  • 33
  • 165
  • 230
  • The easiest way to shuffle in Linq is to use *OrderBy(m => Guid.NewGuid())* – Pauli Østerø Jan 26 '11 at 01:12
  • 3
    @Pauli: It is always easier to write a program that sometimes outputs garbage than one that works reliably. – Timwi Jan 26 '11 at 02:00
  • 1
    Aren't you throwing away the results of the `Shuffle` in your usage example? Shouldn't it be: list.Shuffle().ForEach(method => method()); – jasonh Jan 26 '11 at 02:53
  • 1
    @jasonh: That would work too, and it would do the same thing. The method returns the same list you put in; it makes no difference whether you use that return value or the original list reference. They point to the same list, which is now shuffled. – Timwi Jan 26 '11 at 13:28