如何访问列表中的随机项?

时间:2010-01-07 09:54:37

标签: c# arrays string random

我有一个ArrayList,我需要能够单击一个按钮然后从该列表中随机挑出一个字符串并将其显示在消息框中。

我将如何做到这一点?

12 个答案:

答案 0 :(得分:366)

  1. 在某处创建Random类的实例。请注意,每次需要随机数时都不要创建新实例。您应该重用旧实例以实现生成数字的一致性。你可以在某个地方有一个static字段(小心线程安全问题):

    static Random rnd = new Random();
    
  2. 要求Random个实例为您提供一个随机数字,其中包含ArrayList中项目数的最大值:

    int r = rnd.Next(list.Count);
    
  3. 显示字符串:

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

答案 1 :(得分:125)

我通常使用这一小部分扩展方法:

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

答案 2 :(得分:83)

你可以这样做:

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

答案 3 :(得分:20)

创建Random实例:

Random rnd = new Random();

获取随机字符串:

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

请记住,如果您经常这样做,则应重新使用Random对象。将它作为一个静态字段放在类中,这样它只被初始化一次然后访问它。

答案 4 :(得分:11)

或者像这样简单的扩展类:

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>或数组。

答案 5 :(得分:3)

为什么不:

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

答案 6 :(得分:2)

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

答案 7 :(得分:2)

我建议采用不同的方法,如果列表中项目的顺序在提取时并不重要(每个项目只能选择一次),那么可以使用{{代替List 3}},这是线程安全的无序对象集合:

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

EventHandler:

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

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

答案 8 :(得分:0)

我一直在使用这个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;
}

答案 9 :(得分:0)

我需要更多项目而不是一项。所以,我写了这个:

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

答案 10 :(得分:0)

从JSON文件中随机打印国家名称。
型号:

public class Country
    {
        public string Name { get; set; }
        public string Code { get; set; }
    }

实施:

string filePath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\..\")) + @"Data\Country.json";
            string _countryJson = File.ReadAllText(filePath);
            var _country = JsonConvert.DeserializeObject<List<Country>>(_countryJson);


            int index = random.Next(_country.Count);
            Console.WriteLine(_country[index].Name);

答案 11 :(得分:-1)

为什么不[2]:

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