Відповіді:
Створіть 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
щоб замість цього стати примірник у статичному стані.
Ви можете зробити:
list.OrderBy(x => Guid.NewGuid()).FirstOrDefault()
Створіть Random
примірник:
Random rnd = new Random();
Отримати випадковий рядок:
string s = arraylist[rnd.Next(arraylist.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
ви можете використовувати ConcurrentBag
колекцію, яка є безпечною для потоків, не упорядкованою колекцією об'єкти:
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)];
}