2011-05-02 59 views
0

可能重复:
Most efficient way to randomly “sort” (Shuffle) a list of integers in C#随机列表的副本<T>

如何有效地创建List<T>随机副本?

List<string> myList = new List<string>(); 
myList.Add("A"); 
myList.Add("B"); 
myList.Add("C"); 

// Now an extension method or a function which returns a random arrangement of myList: 

List<string> GetRandomList() 
{ 
    // List<string> result = new List<string>(); 
    // Random rnd = new Random(); 
    // Inside a loop 
    // result.Add(myList[rnd.Next(1, myList.Count)]); 
} 

扩展方法woud是public static List<T> Shuffle(List<T> this)

+0

http://stackoverflow.com/questions/2459264/why-is-fisher-yates-the-most-useful-shuffling-algorithm – 2011-05-02 00:12:51

+0

http://stackoverflow.com/questions/1287567/c-is-using -random-and-orderby-a-good-shuffle-algorithm – 2011-05-02 00:13:09

+0

http://stackoverflow.com/questions/3343797/is-this-c-implementation-of-fisher-yates-shuffle-correct – 2011-05-02 00:13:53

回答

4

你正在寻找一个洗牌,有各种实现在那里,通常Fisher-Yates shuffle

下面从here采取了通用实现:

public static void Shuffle<T>(this IList<T> list) 
{ 
    Random rng = new Random(); 
    int n = list.Count; 
    while (n > 1) { 
     n--; 
     int k = rng.Next(n + 1); 
     T value = list[k]; 
     list[k] = list[n]; 
     list[n] = value; 
    } 
} 

注意,这个重新排序列表到位,它很容易重构它返回一个新的列表,如果这就是你想要做什么。

+0

+1:感谢 – Xaqron 2011-05-02 00:09:13

+0

这个词倒是会改变列表本身,而不是返回一个新的混洗列表。 – Xaqron 2011-05-02 00:28:47

0
public List<T> Random<T>(this IEnumerable<T> collection) 
{ 
    return collection.OrderBy(i => Guid.NewGuid()).ToList(); 
} 

感谢Jeff Atwood for this solution

+0

这只会调用集合中每个项目一次的委托,还是多次?假设我们想要对列表{1,2,3}进行混洗,并且OrderBy实现决定比较'1'和'2',然后比较'1'和'3'。它会调用委托,它将调用'NewGuid',但是当它想要将两个不同的数字比较为1时,它会只调用一次还是多次调用'NewGuid'?如果它多次调用,那么这不会产生好的洗牌,并且最终的顺序在很大程度上取决于OrderBy的实现。 – 2011-05-02 00:55:14

+0

它会多次调用它。 – 2011-05-02 01:12:28

+1

请参阅http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html,了解有关以不良方式进行混洗的结果的有趣分析。在这种情况下,比较函数('int Compare(object a,object b)')返回一个随机数1或-1。由于排序的实施方式,所产生的排序不是随机的,而是因排序实施而有所不同。 – 2011-05-02 04:43:31