문제

'n'항목이있는 컬렉션에서 임의의 셔플 링 된 Count 'n'을 얻는 가장 쉬운 방법을 제안하십시오. 여기서 n <= n

도움이 되었습니까?

해결책

또 다른 옵션은 Orderby를 사용하고 안내 값을 정렬하는 것입니다.

var result = sequence.OrderBy(elem => Guid.NewGuid());

나는 상기가 실제로 무작위 분포를 생성한다는 것을 확신시키기 위해 경험적 테스트를 수행했습니다. 내 결과를 볼 수 있습니다 배열을 무작위로 재정렬하는 기술.

다른 팁

Mquander의 답변과 Dan Blanchard의 의견에 따라 다음은 다음을 수행하는 LINQ 친화적 인 확장 방법이 있습니다. Fisher-Yates-Durstenfeld 셔플:

// take n random items from yourCollection
var randomItems = yourCollection.Shuffle().Take(n);

// ...

public static class EnumerableExtensions
{
    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
    {
        return source.Shuffle(new Random());
    }

    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
    {
        if (source == null) throw new ArgumentNullException("source");
        if (rng == null) throw new ArgumentNullException("rng");

        return source.ShuffleIterator(rng);
    }

    private static IEnumerable<T> ShuffleIterator<T>(
        this IEnumerable<T> source, Random rng)
    {
        var buffer = source.ToList();
        for (int i = 0; i < buffer.Count; i++)
        {
            int j = rng.Next(i, buffer.Count);
            yield return buffer[j];

            buffer[j] = buffer[i];
        }
    }
}

이것은 "무작위 바이어스"와 관련된 몇 가지 문제가 있으며 그것이 최적이 아니라고 확신합니다. 이것은 또 다른 가능성입니다.

var r = new Random();
l.OrderBy(x => r.NextDouble()).Take(n);

혼합 컬렉션은 무작위 순서로 그리고 먼저 n 결과의 항목.

조금 덜 무작위이지만 효율적입니다.

var rnd = new Random();
var toSkip = list.Count()-n;

if (toSkip > 0)
    toSkip = rnd.Next(toSkip);
else
    toSkip=0;

var randomlySelectedSequence = list.Skip(toSkip).Take(n);

나는이 무시 된 방법을 작성합니다.

public static IEnumerable<T> Randomize<T>(this IEnumerable<T> items) where T : class
{
     int max = items.Count();
     var secuencia = Enumerable.Range(1, max).OrderBy(n => n * n * (new Random()).Next());

     return ListOrder<T>(items, secuencia.ToArray());
}

private static IEnumerable<T> ListOrder<T>(IEnumerable<T> items, int[] secuencia) where T : class
        {
            List<T> newList = new List<T>();
            int count = 0;
            foreach (var seed in count > 0 ? secuencia.Skip(1) : secuencia.Skip(0))
            {
                newList.Add(items.ElementAt(seed - 1));
                count++;
            }
            return newList.AsEnumerable<T>();
        }

그런 다음 소스 목록 (모든 항목)이 있습니다.

var listSource = p.Session.QueryOver<Listado>(() => pl)
                        .Where(...);

마지막으로, 나는 "Randomize"라고 부르고 5 개의 항목에 대한 무작위 항목을 수집합니다.

var SubCollection = Randomize(listSource.List()).Take(5).ToList();

못생긴 코드에 대해 죄송합니다 :-), 그러나


var result =yourCollection.OrderBy(p => (p.GetHashCode().ToString() + Guid.NewGuid().ToString()).GetHashCode()).Take(n);

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top