web-dev-qa-db-ja.com

リスト内のランダムな項目にアクセスするには?

ArrayListがあり、ボタンをクリックしてそのリストからランダムに文字列を取り出してメッセージボックスに表示できるようにする必要があります。

これをどのようにして行うのでしょうか。

206
jay_t55
  1. どこかにRandomクラスのインスタンスを作成します。乱数が必要になるたびに新しいインスタンスを作成しないことが非常に重要です。生成された数の統一を図るために、古いインスタンスを再利用する必要があります。あなたはどこかにstaticフィールドを持つことができます(スレッドの安全性の問題に注意してください):

    static Random rnd = new Random();
    
  2. Randomインスタンスに、ArrayList内の最大項目数の乱数を与えるように依頼します。

    int r = rnd.Next(list.Count);
    
  3. 文字列を表示します。

    MessageBox.Show((string)list[r]);
    
369
Mehrdad Afshari

私は通常、この小さな拡張メソッドのコレクションを使います。

public static class EnumerableExtension
{
    public static T PickRandom<T>(this IEnumerable<T> source)
    {
        return source.PickRandom(1).Single();
    }

    public static IEnumerable<T> PickRandom<T>(this IEnumerable<T> source, int count)
    {
        return source.Shuffle().Take(count);
    }

    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
    {
        return source.OrderBy(x => Guid.NewGuid());
    }
}

強く型付けされたリストのために、これはあなたが書くことを可能にするでしょう:

var strings = new List<string>();
var randomString = strings.PickRandom();

あなたが持っているのがArrayListだけなら、あなたはそれをキャストすることができます:

var strings = myArrayList.Cast<string>();
127
Mark Seemann

できるよ:

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

Randomインスタンスを作成します。

Random rnd = new Random();

ランダムな文字列を取得します:

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

ただし、これを頻繁に行う場合はRandomオブジェクトを再利用する必要があります。それをクラス内の静的フィールドとして置くので、一度だけ初期化されてからアクセスされます。

20
Joey

またはこのような単純な拡張クラス:

public static class CollectionExtension
{
    private static Random rng = new Random();

    public static T RandomElement<T>(this IList<T> list)
    {
        return list[rng.Next(list.Count)];
    }

    public static T RandomElement<T>(this T[] array)
    {
        return array[rng.Next(array.Length)];
    }
}

それからちょうど呼んでください:

myList.RandomElement();

配列にも使えます。

OrderBy()を呼び出すのは避けましょう。コレクションが大きいとコストがかかる可能性があるからです。この目的のためにList<T>または配列のようなインデックス付きのコレクションを使用してください。

12
Dave_cz

何故なの:

public static T GetRandom<T>(this IEnumerable<T> list)
{
   return list.ElementAt(new Random(DateTime.Now.Millisecond).Next(list.Count()));
}
3
Lucas
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].ToString());
2
Rajesh Varma

1つだけではなくもっと多くのアイテムが必要でした。だから、私はこれを書いた:

public static TList GetSelectedRandom<TList>(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;
}

これを使えば、このようにランダムに好きなだけ要素を得ることができます。

var _allItems = new List<TModel>()
{
    // ...
    // ...
    // ...
}

var randomItemList = _allItems.GetSelectedRandom(10); 
0
bafsar

私はしばらくこのExtensionMethodを使っています:

public static IEnumerable<T> GetRandom<T>(this IEnumerable<T> 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;
}
0
Carlos Toledo