我有一个数组列表,我需要能够点击一个按钮然后从列表中随机挑选一个字符串并显示在消息框中。

我该怎么做呢?


当前回答

你可以:

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

其他回答

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());

我通常使用这个扩展方法的小集合:

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();

如果你只有一个数组列表,你可以强制转换它:

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

我将建议不同的方法,如果列表中项目的顺序在提取时并不重要(并且每个项目应该只选择一次),那么您可以使用ConcurrentBag,而不是list,它是线程安全的,无序的对象集合:

var bag = new ConcurrentBag<string>();
bag.Add("Foo");
bag.Add("Boo");
bag.Add("Zoo");

事件:

string result;
if (bag.TryTake(out result))
{
    MessageBox.Show(result);
}

TryTake将尝试从无序集合中提取一个“随机”对象。

为什么不[2]:

public static T GetRandom<T>(this List<T> list)
{
     return list[(int)(DateTime.Now.Ticks%list.Count)];
}

我已经使用这个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;
}