我正在嘗試為通用陣列制作擴展方法,所以我可以取出隨機的元素集。
我為型別制作了以下擴展方法List<T>,它們作業得很好,但我不知道如何對泛型陣列做同樣的事情:
public static T Random<T>(this List<T> list)
{
return list[GameManager.instance.functions.RandomInt(list.Count - 1)];
}
public static IEquatable Random<IEquatable>(this List<IEquatable> list, List<IEquatable> hits)
{
int rand = GameManager.instance.functions.RandomInt(list.Count - 1);
while (hits.Exists(h => h.Equals(list[rand])))
rand = GameManager.instance.functions.RandomInt(list.Count - 1);
return list[rand];
}
public static List<T> Random<T>(this List<T> list, int count)
{
List<T> result = new List<T>();
for (int i = 0; i < count; i )
{
result.Add(list.Random());
}
return result;
}
public static List<IEquatable> RandomUnique<IEquatable>(this List<IEquatable> list, int count)
{
List<IEquatable> result = new List<IEquatable>();
for (int i = 0; i < count; i )
{
result.Add(list.Random(result));
}
return result;
}
我試影像這樣修改第一種方法:
public static IEnumerable Random<IEnumerable>(this IEnumerable list)
但它不能識別list為陣列,所以我無法得到它的長度值。
我看到了一種解決方法,從陣列中創建一個串列,然后獲取我的隨機值并再次創建陣列,但這似乎只是采取例如太多的行動。2 個隨機來自 4 個元素的陣列。
請告知
編輯:
感謝Mathew的評論,我設法正確構造了泛型陣列的擴展方法:
public static T Random<T>(this T[] list)
{
return list[GameManager.instance.functions.RandomInt(list.Length - 1)];
}
但最終我會嘗試使用 Dmitry 的答案,并嘗試為 IEnumerable 制作這些內容。非常感謝!
EDIT2:
感謝 Zastai,我更改了所有方法,因此它們適用于 List 和泛型陣列:
public static T Random<T>(this IReadOnlyList<T> list)
{
return list[GameManager.instance.functions.RandomInt(list.Count - 1)];
}
public static IEquatable Random<IEquatable>(this IReadOnlyList<IEquatable> list, List<IEquatable> hits)
{
int rand = GameManager.instance.functions.RandomInt(list.Count - 1);
while (hits.Exists(h => h.Equals(list[rand])))
rand = GameManager.instance.functions.RandomInt(list.Count - 1);
return list[rand];
}
public static List<T> Random<T>(this IReadOnlyList<T> list, int count)
{
List<T> result = new();
for (int i = 0; i < count; i )
{
result.Add(list.Random());
}
return result;
}
public static List<IEquatable> RandomUnique<IEquatable>(this IReadOnlyList<IEquatable> list, int count)
{
List<IEquatable> result = new();
for (int i = 0; i < count; i )
{
result.Add(list.Random(result));
}
return result;
}
不適用于字串(如 中"abcdefg".Random()),但根據我的需要,它不是必需的。
uj5u.com熱心網友回復:
您可以嘗試為 實作
單個例程,而不是為等實作擴展方法List<T>,例如T[]IEnumerable<T>
public static partial class EnumerableExtensions {
public static T Random<T>(this IEnumerable<T> source) {
//DONE: do not forget to validate public methods' arguments
if (source is null)
throw new ArgumentNullException(nameof(source));
// If enumerable is a collection (array, list) we can address items explictitly
if (source is ICollection<T> collection) {
if (collection.Count <= 0)
throw new ArgumentOutOfRangeException(nameof(source),
$"Empty {nameof(source)} is not supported.");
return collection[GameManager.instance.functions.RandomInt(collection.Count - 1)];
}
// In general case we have to materialize the enumeration
var list = source.ToList();
if (list.Count <= 0)
throw new ArgumentOutOfRangeException(nameof(source),
$"Empty {nameof(source)} is not supported.");
return list[GameManager.instance.functions.RandomInt(list.Count - 1)];
}
}
然后你可以對串列、陣列等使用相同的擴展方法:
// Array
int demo1 = new int[] {4, 5, 6}.Random();
// List
double demo2 = new List<double>() {1.0. 3.0}.Random();
// String is not array or list but implements IEnumerable<char>
char demo3 = "abcdef".Random();
uj5u.com熱心網友回復:
IEnumerable具體來說只是一個值序列,沒有長度。
IReadOnlyList另一方面,它是一個值串列(確實有一個長度),并且不允許添加/洗掉值。
一個 .NET 陣列實作了這兩者。
因此,如果您將擴展方法更改為 takeIReadOnlyList<xxx>而不是List<xxx>它們也應該自動在陣列上作業。
uj5u.com熱心網友回復:
作為替代考慮:您可以使用從未知長度的序列中Reservoir sampling選擇N專案。
這是一個示例實作:
/// <summary>Randomly selects n elements from a sequence of items.</summary>
public static List<T> RandomlySelectedItems<T>(IEnumerable<T> items, int n, System.Random rng)
{
// See http://en.wikipedia.org/wiki/Reservoir_sampling for details.
var result = new List<T>(n);
int index = 0;
foreach (var item in items)
{
if (index < n)
{
result.Add(item);
}
else
{
int r = rng.Next(0, index 1);
if (r < n)
result[r] = item;
}
index;
}
if (index < n)
throw new ArgumentException("Input sequence too short");
return result;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/494042.html
下一篇:未找到配置管理器
