Based on the discussion in the comments, when a card has multiple colours, you want to select a single colour (the one that appears first in a priority list), and sort it on that basis.
// Higher-priority colours come first
var coloursPriority = new List<string>() { "W", "U", "B", "R", "G" };
// Turn the card's colour into an index. If the card has multiple colours,
// pick the smallest of the corresponding indexes.
cards.OrderBy(card => card.Colours.Select(colour => coloursPriority.IndexOf(colour)).Min());
Responding to the discussion in the comments: if you wanted to sort the cards based first on their highest-priority colour, and then by their next-highest-priority colour, etc, then this is a reasonably efficient way of doing it:
public class CardColourComparer : IComparer<List<int>>
{
public static readonly CardColourComparer Instance = new CardColourComparer();
private CardColourComparer() { }
public int Compare(List<int> x, List<int> y)
{
// Exercise for the reader: null handling
// For each list, compare elements. The lowest element wins
for (int i = 0; i < Math.Min(x.Count, y.Count); i++)
{
int result = x[i].CompareTo(y[i]);
if (result != 0)
{
return result;
}
}
// If we're here, then either both lists are identical, or one is shorter, but it
// has the same elements as the longer one.
// In this case, the shorter list wins
return x.Count.CompareTo(y.Count);
}
}
Then
// Higher-priority colours come first
var coloursPriority = new List<string>() { "W", "U", "B", "R", "G" };
cards.OrderBy(card =>
card.Colours.Select(colour => coloursPriority.IndexOf(colour)).OrderBy(x => x).ToList(),
CardColourComparer.Instance);
This takes advantage of the fact that OrderBy
applies the keySelector
delegate to each item once only. We use this to turn each card into a list containing the priority of each of its colours (higher priorities have lower values), ordered with the higher-priority ones first. We then sort these keys, using a custom comparer which compares two of these lists.
Note that this doesn't care about the order of the colours associated with each card: [W, U]
will sort the same as [U, W]
. To take the order into account (so [W]
comes before [W, U]
comes before [U, W]
, do this:
cards.OrderBy(card =>
card.Colours.Select(colour => coloursPriority.IndexOf(colour)).ToList(),
CardColourComparer.Instance);