可能重复:
C#: Is using Random and OrderBy a good shuffle algorithm?
我想创建一个扩展方法,该方法应该对集合中的项进行随机播放。
我可以改进以下内容吗?
public static IList<T> RandomList<T>(this IList<T> source)
{
if (source.Count <= 0) throw new ArgumentException("No Item to Randomize");
for (int i =source.Count-1 ; i>0; i--)
{
int RandomIndex = Rnd.Next(i + 1);
T temp = source[i];
source[i] = source[RandomIndex];
source[RandomIndex] = temp;
}
return source;
}
答案 0 :(得分:5)
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
{
foreach(var item in source.OrderBy(i => Guid.NewGuid()))
{
yield return item;
}
}
答案 1 :(得分:1)
只要你知道Random is not very random.
,我认为这就足够了随机类适用于简单游戏和其他非科学领域。不要将它用于加密。
答案 2 :(得分:1)
通常,您应该避免更改列表,而是返回一个新列表。更好的方法是返回IEnumerable以与其他Extension方法和LINQ保持一致。
试试这个。
public static class RandomizeExtensionMethods
{
private static readonly Random _random = new Random();
public static IEnumerable<T> Randomize<T>(this IList<T> enumerable)
{
if (enumerable == null || enumerable.Count == 0)
{
return new List<T>(0);
}
return RandomizeImpl(enumerable);
}
public static IEnumerable<T> RandomizeImpl<T>(this IList<T> enumerable)
{
var indices = new int[enumerable.Count];
for(int i=0; i<indices.Length; i++)
{
indices[i] = i;
}
lock (_random)
{
for (int i = 0; i < indices.Length - 1; i++)
{
int j = _random.Next(i, indices.Length);
int swap = indices[j];
indices[j] = indices[i];
indices[i] = swap;
}
}
for(int i=0; i<indices.Length; i++)
{
yield return enumerable[indices[i]];
}
}
}
答案 3 :(得分:1)
我对这种方法有一些问题:
本质:
public static IList<T> Shuffled<T>(this IEnumerable<T> source, Random generator)
{
if (source == null) throw new ArgumentNullException("source");
if (generator == null) throw new ArgumentNullException("generator");
//copy
var result = source.ToList();
//shuffle the copy
for (int i = result.Count - 1; i > 0; i--)
{
int RandomIndex = generator.Next(i + 1);
T temp = result[i];
result[i] = result[RandomIndex];
result[RandomIndex] = temp;
}
return result;
}
我没有概括输出类型。如果你愿意,你可以这样做。
答案 4 :(得分:0)
让它返回本身有点多余。如果您要返回列表的深层副本,请确保;在这种情况下,它应该被称为“GetShuffledCopy()”或类似的东西。如果你在列表本身上行动,它应该是一个无效的回报,并被称为“Shuffle()”
-Oisin