2012-05-28 23 views
6

Có vẻ như đây là một nhiệm vụ dễ dàng nhưng tôi không thể tìm ra cách để làm điều này với LINQ. Thông tin duy nhất tôi có thể tìm thấy cho đến nay là về định dạng giải đấu vòng tròn, đó không phải là những gì tôi theo sau. Tôi có thể đang tìm kiếm sai. Căn cứ vào danh sách sau đây:Thứ tự LINQ bởi "round robin"

var items [] { "apple", "banana", "banana", "candy", "banana", "fruit", "apple" }; 

Làm thế nào tôi có thể sắp xếp này (tốt nhất là sử dụng LINQ) để nó đi ra trong "round robin" trật tự, có nghĩa là, chọn từng mục riêng biệt một lần trước khi lặp đi lặp lại. Vì vậy, trong danh sách trên sẽ đi ra như thế này (Nó không quan trọng nếu nó đi ra trong thứ tự chữ cái, mặc dù danh sách này không):

var sorted [] { "apple", "banana", "candy", "fruit", "apple", "banana", "banana" }; 

Tôi biết tôi có thể làm điều này bằng cách duyệt qua nó một cách khó khăn, tôi đã hy vọng điều gì đó dễ dàng hơn. Có ai có bất kỳ cái nhìn sâu sắc làm thế nào để làm điều này? Cảm ơn trước!

+0

Bạn có thể giải thích chính xác ý nghĩa của việc phân loại "round-robin" không? – mattytommo

+0

Anh ấy có nghĩa là "round-robin" sắp xếp http://en.wikipedia.org/wiki/Round-robin – Likurg

Trả lời

8
var sorted = items.GroupBy(s => s) 
    .SelectMany(grp => grp.Select((str, idx) => new { Index = idx, Value = str })) 
    .OrderBy(v => v.Index).ThenBy(v => v.Value) 
    .Select(v => v.Value) 
    .ToArray(); 
+0

shoulda học cách copypaste đúng cách. chấp nhận điều này, điều này hoạt động. – Alex

+1

cách tiếp cận tốt đẹp, tôi thích nó! – HugoRune

+0

Bạn rất tuyệt vời. Nó hoạt động hoàn hảo. Cảm ơn bạn! Tất cả những gì tôi cần thay đổi là GroupBy cho dự án của mình để nhóm theo mục duy nhất thực sự mà tôi quan tâm, phần còn lại là sao chép-dán. Cảm ơn một lần nữa! – Eric

0

Tôi đã làm điều này một lần, đào lên mã:

//Originially written for lists, all you need is prepend a .ToList() where needed to apply this to an array 
List<string> src = new List<string> { "string1", "string2" }; //source 
List<string> dst = new List<string>(); 

dst.AddRange(src.Distinct()); 
dst.ForEach(d => src.RemoveAt(src.FindIndex(i => i.Equals(d)))); //remove the first occurrence of each distinct element 
dst.AddRange(src); 
0

Chỉ cần thấy rằng hai câu trả lời hiện lên khi tôi đang viết này; ồ, đây là một cách khác:

var items [] { "apple", "banana", "banana", "candy", "banana", "fruit", "apple" }; 

var uniqueItems = items.Distinct().OrderBy(item => item); // alphabetical orderBy is optional 

var duplicateItems = items 
        .GroupBy(item => item) 
        .SelectMany(group => group.Skip(1)) 
        .OrderBy(item => item); // alphabetical orderBy is optional; 

var sorted = uniqueItems.Append(duplicateItems).ToArray(); 
Các vấn đề liên quan