Hãy gợi ý cách dễ nhất để có được một bộ sưu tập ngẫu nhiên xáo trộn đếm 'n' từ bộ sưu tập có các mục 'N'. trong đó n < = NTruy vấn LINQ tối ưu để có được một bộ sưu tập phụ ngẫu nhiên - Trộn ngẫu nhiên
Trả lời
Một lựa chọn khác là sử dụng OrderBy và để sắp xếp trên một giá trị GUID, mà bạn có thể làm như vậy bằng:
var result = sequence.OrderBy(elem => Guid.NewGuid());
tôi đã làm một số xét nghiệm thực nghiệm để thuyết phục bản thân mình rằng trên thực sự tạo ra một phân phối ngẫu nhiên (mà nó xuất hiện làm). Bạn có thể xem kết quả của tôi tại Techniques for Randomly Reordering an Array.
Shuffle việc thu thập theo thứ tự ngẫu nhiên và lấy n
mục đầu tiên từ kết quả.
Lưu ý rằng bạn không phải trộn hoàn toàn bộ sưu tập khi n
Tiếp tục câu trả lời mquander và bình luận Dan Blanchard của, đây là một phương pháp khuyến nông LINQ thân thiện mà thực hiện một Fisher-Yates-Durstenfeld shuffle:
// 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];
}
}
}
+1 Linqy và hiệu quả. Mũ tắt :) –
Có phải tôi hoặc phương pháp này sẽ làm hỏng chỉ mục danh sách? Bất cứ khi nào sử dụng elementAt() sau khi xáo trộn kết quả tôi nhận được là hoàn toàn bất ngờ ... – Htbaa
@Htbaa: Phương thức trả về một chuỗi được đánh giá lười biếng. Nếu bạn thực hiện 'seq.Shuffle(). ElementAt (n)' nhiều lần thì bạn đang xáo trộn mỗi lần, vì vậy có khả năng bạn sẽ nhận được một mục khác ở vị trí 'n'. Nếu bạn muốn shuffle * once * thì bạn cần lưu trữ chuỗi trong một tập hợp cụ thể của một số loại: ví dụ, 'var list = seq.Shuffle(). ToList()'. Sau đó, bạn có thể làm 'list.ElementAt (n)' thường xuyên như bạn muốn - hoặc chỉ 'list [n]' - và bạn sẽ luôn nhận được cùng một mục. – LukeH
Xin lỗi vì xấu xí đang :-), nhưng
var result =yourCollection.OrderBy(p => (p.GetHashCode().ToString() + Guid.NewGuid().ToString()).GetHashCode()).Take(n);
'p.GetHashCode(). ToString() + Guid.NewGuid(). ToString()). GetHashCode()' không phải là ngẫu nhiên. Nó có thể trông ngẫu nhiên, nhưng nó không phải. Bạn nên sử dụng RNG cho ngẫu nhiên - các nhà khoa học dữ liệu đã thiết kế chúng một cách cụ thể để có thể ngẫu nhiên nhất có thể. – Enigmativity
này có một số vấn đề với "xu hướng ngẫu nhiên" và tôi chắc chắn nó không tối ưu, đây là một khả năng khác:
var r = new Random();
l.OrderBy(x => r.NextDouble()).Take(n);
Điều này không có bất kỳ sai lệch ngẫu nhiên nào ngoài bất kỳ sai lệch không đáng kể nào từ 'Random'. Nó cũng rất hiệu quả. – Enigmativity
Đến đây để đề xuất điều này. Đây sẽ là câu trả lời được chấp nhận. –
Tôi viết những dòng này sẽ ghi đè phương pháp:
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>();
}
Sau đó, tôi có danh sách nguồn của tôi (tất cả các mục)
var listSource = p.Session.QueryOver<Listado>(() => pl)
.Where(...);
Cuối cùng, tôi gọi là "Randomize" và tôi nhận được một ngẫu nhiên phụ thu các mặt hàng, trong trường hợp của tôi, 5 hạng mục:
var SubCollection = Randomize(listSource.List()).Take(5).ToList();
Bạn đang lãng phí bộ nhớ bằng cách tạo 'newList'. Có thể xem xét sử dụng 'lợi nhuận' bên trong câu lệnh' foreach'. – bradlis7
Dòng 'Enumerable.Range (1, max) .OrderBy (n => n * n * (new Random()). Next())' là khủng khiếp - nó không phải ngẫu nhiên chút nào. Tiếp theo() 'như vậy sẽ chỉ trả về cùng một số trong hầu hết các trường hợp và' n * n' làm cho số bị sai lệch - và có thể có thể gây ra các ngoại lệ tràn. – Enigmativity
Một chút ít ngẫu nhiên, nhưng hiệu quả:
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);
- 1. Bộ sưu tập ngẫu nhiên Java
- 2. Thuật toán trộn ngẫu nhiên
- 3. In một hàng ngẫu nhiên từ truy vấn mysql
- 4. số ngẫu nhiên không quá ngẫu nhiên
- 5. linq chọn một hàng ngẫu nhiên
- 6. Tại sao không ngẫu nhiên() ngẫu nhiên?
- 7. Trình tạo số ngẫu nhiên phân phối ngẫu nhiên
- 8. Hàng ngẫu nhiên từ LINQ đến Sql
- 9. Tài liệu ngẫu nhiên Mongoid
- 10. Thuật toán trộn ngẫu nhiên có thể sử dụng phím
- 11. Số ngẫu nhiên hoặc số dương Javascript ngẫu nhiên
- 12. Tổng hợp ngẫu nhiên?
- 13. số C# ngẫu nhiên không là "ngẫu nhiên"
- 14. Cuộc gặp gỡ ngẫu nhiên không quá ngẫu nhiên
- 15. Bảng IE9 có các hàng ngẫu nhiên được bù trừ tại các cột ngẫu nhiên
- 16. MongoDB: cách hiệu quả nhất để truy vấn một tài liệu ngẫu nhiên là gì?
- 17. Tạo chuỗi ngẫu nhiên
- 18. Trường ngẫu nhiên có điều kiện
- 19. MySQL: Cách truy xuất hàng ngẫu nhiên hoặc nhiều hàng ngẫu nhiên?
- 20. C# Ngẫu nhiên (Dài)
- 21. Giá trị ngẫu nhiên trong truy vấn MySql với pagination
- 22. Truy cập ngẫu nhiên vào luồng gzip
- 23. random.choice không ngẫu nhiên
- 24. ngẫu nhiên chuỗi C#
- 25. Cách ngẫu nhiên trộn các giá trị trong bản đồ?
- 26. Số nguyên ngẫu nhiên
- 27. Số ngẫu nhiên Javascript?
- 28. Tạo ID ngẫu nhiên nhỏ
- 29. gấu trúc đi bộ ngẫu nhiên
- 30. Ngẫu nhiên trong Jython
Giải pháp này vi phạm hợp đồng đặt hàng, cụ thể là một đối tượng nhất định có khóa nhất quán trong toàn bộ sắp xếp. Nếu nó hoạt động, nó làm như vậy thông qua cơ hội một mình, và có thể phá vỡ trong các phiên bản tương lai của khuôn khổ. Để biết thêm chi tiết, hãy xem http://blogs.msdn.com/b/ericlippert/archive/2011/01/31/spot-the-defect-bad-comparisons-part-four.aspx –
Bắt tốt. Tuy nhiên, nếu điều này được cam kết với một bộ sưu tập thực tế - chẳng hạn như thêm .ToList() hoặc .ToArray() vào cuối -, thì không có cơ hội nào của bộ sưu tập nhận mã LINQ được xử lý/lặp lại nhiều lần để thực hiện sắp xếp. Tôi tưởng tượng rằng sẽ tồn tại trong tương lai nâng cấp cũng vì nó sẽ hoạt động như một ảnh chụp dự đoán được. – MutantNinjaCodeMonkey
Tôi chỉ tình cờ gặp trang này và nghĩ nó thật tuyệt vời, nhưng tôi không hiểu lời bình luận. những gì có thể có thể đi sai trong việc sử dụng phương pháp này để trộn một bộ sưu tập (tôi không hỏi rằng mỉa mai, tôi thực sự tò mò về khả năng)? – SelAromDotNet