답변:
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()
또는 다음과 같은 간단한 확장 클래스 :
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
method 의 매개 변수 Next
는 목록에서 하나의 요소가 아닌 여러 요소 여야 한다고 말하고 싶습니다 .
이 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;
}
A는 대신 다음, 목록 내에서 항목의 순서가 추출에서 중요하지 않은 경우 나, 다른 접근 방식을 제안합니다 (각 항목은 한 번만 선택해야합니다) 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; }
}
Implementaton :
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)];
}