Answers:
在Random
某处创建类的实例。请注意,每次需要随机数时都不要创建新实例,这一点非常重要。您应该重用旧实例以实现生成数字的一致性。您可以在static
某处有一个字段(请注意线程安全性问题):
static Random rnd = new Random();
要求Random
实例给您一个随机数,其中包含最大数量的项目ArrayList
:
int r = rnd.Next(list.Count);
显示字符串:
MessageBox.Show((string)list[r]);
Next(max)
呼叫的上限是唯一的。
我通常使用这种扩展方法的小集合:
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>();
return list[rnd.Next(list.Count)];
Random
改为持有静态实例。
或像这样的简单扩展类:
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>
为此,请使用诸如或数组的索引集合。
IList
因此不需要第二次重载。
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());
maxValue
方法的参数Next
应该只是列表中的多个元素,而不是减一个,因为根据文档“ maxValue是随机数的唯一上限 ”。
我已经使用此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;
}
我会建议采用其他方法,如果列表中项目的顺序在提取时并不重要(每个项目只能选择一次),那么List
可以使用a ConcurrentBag
作为线程安全的无序集合,而不是a 对象:
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);
}
该TryTake
会尝试从无序集合提取一个“随机”的对象。
我需要更多的物品,而不仅仅是一件。所以,我这样写:
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);
从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);
为什么不[2]:
public static T GetRandom<T>(this List<T> list)
{
return list[(int)(DateTime.Now.Ticks%list.Count)];
}