Astuce : RandomOrDefault

Par défaut

Nouvelle section du blog avec  des astuces et des bouts de code que j’utilise régulièrement. L’idée ici n’est pas de faire de long discours, je ne rentrerai pas dans le détail, mais plutôt de vous « offrir » tout cela sans chichi…

Pour commencer donc, voici des méthodes d’extensions basées sur les méthodes First(), FirstOrDefault() et compagnies et qui permet de prendre un élément aléatoirement dans une liste.

/// <summary>
///     Get a random element of source
/// </summary>
/// <typeparam name="TSource">Source element Type</typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static TSource Random<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw new ArgumentNullException("source");
    }

    var list = source as IList<TSource>;
    if (list != null)
    {
        if (list.Count > 0)
        {
            var rnd = new Random();
            var index = rnd.Next(list.Count - 1);
            return list[index];
        }
    }
    else
    {
        var count = source.Count();
        if (count > 0)
        {
            if (count == 1)
                return source.Single();

            var rnd = new Random();
            var index = rnd.Next(count - 1);
            return source.Skip(index).First();
        }
    }
    throw new InvalidOperationException("No element");
}

/// <summary>
///     Get a random element of source
/// </summary>
/// <typeparam name="TSource">Source element type</typeparam>
/// <param name="source"></param>
/// <param name="predicate">Filter</param>
/// <returns></returns>
public static TSource Random<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null)
    {
        throw new ArgumentNullException("source");
    }

    if (predicate == null)
    {
        throw new ArgumentNullException("predicate");
    }

    var r = source.Where(predicate);
    if (r.Any())
    {
        return r.Random();
    }
    throw new InvalidOperationException("No element");
}

/// <summary>
///     Get a random element of source or TSource default value
/// </summary>
/// <typeparam name="TSource">Source element type</typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static TSource RandomOrDefault<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
        throw new ArgumentNullException("source");

    var list = source as IList<TSource>;
    if (list != null)
    {
        if (list.Count > 0)
        {
            var rnd = new Random();
            var index = rnd.Next(list.Count - 1);
            return list[index];
        }
    }
    else
    {
        var count = source.Count();
        if (count > 0)
        {
            if (count == 1)
                return source.Single();

            var rnd = new Random();
            var index = rnd.Next(count - 1);
            return source.Skip(index).First();
        }
    }

    return default(TSource);
}

/// <summary>
///     Get a random element of source or TSource default value
/// </summary>
/// <typeparam name="TSource">Source element type</typeparam>
/// <param name="source"></param>
/// <param name="predicate">Filter</param>
/// <returns></returns>
public static TSource RandomOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null)
    {
        throw new ArgumentNullException("source");
    }

    if (predicate == null)
    {
        throw new ArgumentNullException("predicate");
    }

    var r = source.Where(predicate);
    if (r.Any())
    {
        return r.Random();
    }
    return default(TSource);
}

Et voilà !
N’hésitez pas à me remonter d’éventuelles remarques, bug, améliorations…

Une réflexion sur “Astuce : RandomOrDefault

Votre commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l’aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l’aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s