Accéder à un élément aléatoire dans la liste

J’ai une ArrayList, et je dois pouvoir cliquer sur un bouton, puis sélectionner au hasard une chaîne de cette liste et l’afficher dans une boîte de message.

Comment pourrais-je y aller?

  1. Créez une instance de classe Random quelque part. Notez qu’il est très important de ne pas créer une nouvelle instance chaque fois que vous avez besoin d’un nombre aléatoire. Vous devez réutiliser l’ancienne instance pour uniformiser les nombres générés. Vous pouvez avoir un champ static quelque part (faites attention aux problèmes de sécurité des threads):

     static Random rnd = new Random(); 
  2. Demandez à l’instance Random de vous donner un nombre aléatoire avec le maximum du nombre d’éléments dans ArrayList :

     int r = rnd.Next(list.Count); 
  3. Affiche la chaîne:

     MessageBox.Show((ssortingng)list[r]); 

J’utilise habituellement cette petite collection de méthodes d’extension:

 public static class EnumerableExtension { public static T PickRandom(this IEnumerable source) { return source.PickRandom(1).Single(); } public static IEnumerable PickRandom(this IEnumerable source, int count) { return source.Shuffle().Take(count); } public static IEnumerable Shuffle(this IEnumerable source) { return source.OrderBy(x => Guid.NewGuid()); } } 

Pour une liste fortement typée, cela vous permettrait d’écrire:

 var ssortingngs = new List(); var randomSsortingng = ssortingngs.PickRandom(); 

Si tout ce que vous avez est une ArrayList, vous pouvez la lancer:

 var ssortingngs = myArrayList.Cast(); 

Tu peux faire:

 list.OrderBy(x => Guid.NewGuid()).FirstOrDefault() 

Créez une instance Random :

 Random rnd = new Random(); 

Récupère une chaîne aléatoire:

 ssortingng s = arraylist[rnd.Next(arraylist.Count)]; 

Rappelez-vous cependant que si vous faites cela fréquemment, vous devriez réutiliser l’object Random . Mettez-le en tant que champ statique dans la classe afin qu’il ne soit initialisé qu’une seule fois, puis y accédez.

Ou simple classe d’extension comme ceci:

 public static class CollectionExtension { private static Random rng = new Random(); public static T RandomElement(this IList list) { return list[rng.Next(list.Count)]; } public static T RandomElement(this T[] array) { return array[rng.Next(array.Length)]; } } 

Alors appelez simplement:

 myList.RandomElement(); 

Fonctionne également pour les tableaux.

OrderBy() appeler OrderBy() car il peut être coûteux pour les grandes collections. Utilisez des collections indexées comme List ou des tableaux à cet effet.

 ArrayList ar = new ArrayList(); ar.Add(1); ar.Add(5); ar.Add(25); ar.Add(37); ar.Add(6); ar.Add(11); ar.Add(35); Random r = new Random(); int index = r.Next(0,ar.Count-1); MessageBox.Show(ar[index].ToSsortingng()); 

Pourquoi pas:

 public static T GetRandom(this IEnumerable list) { return list.ElementAt(new Random(DateTime.Now.Millisecond).Next(list.Count())); } 

J’avais besoin de plus d’articles au lieu d’un seul. Donc, j’ai écrit ceci:

 public static TList GetSelectedRandom(this TList list, int count) where TList : IList, new() { var r = new Random(); var rList = new TList(); while (count > 0 && list.Count > 0) { var n = r.Next(0, list.Count); var e = list[n]; rList.Add(e); list.RemoveAt(n); count--; } return rList; } 

Avec cela, vous pouvez obtenir des éléments combien vous voulez aussi au hasard comme ceci:

 var _allItems = new List() { // ... // ... // ... } var randomItemList = _allItems.GetSelectedRandom(10); 

J’utilise cette méthode d’extension depuis un moment:

 public static IEnumerable GetRandom(this IEnumerable list, int count) { if (count <= 0) yield break; var r = new Random(); int limit = (count * 10); foreach (var item in list.OrderBy(x => r.Next(0, limit)).Take(count)) yield return item; }