Esempio n. 1
0
        /// <summary>
        /// Performs a high-quality random shuffling of the list.
        /// Uses a user-provided random number generator, which
        /// </summary>
        /// <typeparam name="T">The type of elements in the list.</typeparam>
        /// <typeparam name="N">The type of numbers generated by the random numbers generator.</typeparam>
        /// <param name="list">The calling list object.</param>
        /// <param name="generator">A floating-point random number generator for the <typeparamref name="N"/> type.</param>
        /// <param name="numericComparer">An optional numeric comparer for <typeparamref name="N"/> type. If <c>null</c>, a standard comparer will be used (if exists, otherwise, an exception will be thrown).</param>
        public static void Shuffle <T, N>(this IList <T> list, IRandomFloatingPoint <N> generator, IComparer <N> numericComparer = null)
        {
            Contract.Requires <ArgumentNullException>(list != null, "list");
            Contract.Requires <ArgumentNullException>(generator != null, "generator");

            if (numericComparer == null)
            {
                numericComparer = Comparer <N> .Default;
            }

            // Генерируем массив пар со случайными ключами,
            // сортируем их по ключу (а значения оказываются случайно перемешанными).

            List <KeyValuePair <N, T> > pairList = new List <KeyValuePair <N, T> >(list.Count);

            foreach (T element in list)
            {
                pairList.Add(new KeyValuePair <N, T>(generator.Next_SingleInterval(), element));
            }

            IComparer <KeyValuePair <N, T> > pairComparer = numericComparer.createKVPComparerOnKey <N, T>();

            pairList.Sort(pairComparer);

            // Восстанавливаем.

            for (int i = 0; i < pairList.Count; i++)
            {
                list[i] = pairList[i].Value;
            }
        }