LINQ order by "round robin"
Asked Answered
C

3

6

Seems like this should be an easy task but I can't figure out how to do this with LINQ. The only information I've been able to find so far is regarding the round robin tournament format, which isn't what I'm after. I may be searching wrong. Given the following list:

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

How can I sort this (preferably using linq) so that it comes out in "round robin" order, that is, select each unique item once before repeats. So the above list would come out like this (It's not important if it comes out in alphabetical order, even though this list does):

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

I know I can do this by iterating over it the hard way, I was just hoping for something easier. Does anyone have any insight how to do this? Thanks in advance!

Cumming answered 28/5, 2012 at 11:5 Comment(2)
Can you explain exactly what you mean by "round-robin" sorting?Ashleighashlen
He mean "round-robin" sorting en.wikipedia.org/wiki/Round-robinWheatear
A
10
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();
Ankylosis answered 28/5, 2012 at 11:34 Comment(2)
shoulda learn to copypaste properly. accept this, this works.Vanhook
You sir are awesome. It works perfectly. Thank you! All I needed to change was the GroupBy for my project in order to group by the actual unique item I cared about, the rest was literally copy-paste. Thanks again!Cumming
V
0

I did this once, dug up the code:

//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);
Vanhook answered 28/5, 2012 at 11:34 Comment(0)
O
0

Just saw that two answers popped up while I was writing this; oh well, here is another way:

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();
Oliguria answered 28/5, 2012 at 11:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.