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”