Similar to this Java question I want to sort a List<T>
where a known set of values should come first (if present), after which we use the default order - e.g. EqualityComparer<T>.Default
. Efficient code is desirable, but I'm more interested in a clever LINQ
expression.
Sample data
Known: e c
Input: c b e d a
Output: e c a b d
Known: e c
Input: b a c e c
Output: e c c a b
Known: e c
Input: b d f a
Output: a b d f
Wanted API
Some minor tweaks might be necessary. Note the keySelector
, allowing us to choose a property as sorting target.
public static class EnumerableExtensions
{
public static IEnumerable<TSource> Sort<TSource, TKey>(
this IEnumerable<TSource> input,
Func<TSource, TKey> keySelector, TKey[] knownValues)
{
// TODO: Clever LINQ implementation here!
yield break;
}
}
Sample program
class Program
{
public class Foo
{
public Foo(string name) => Name = name;
public string Name { get; }
public override string ToString() => Name;
}
public static void Main()
{
string[] knownValues = { "e", "c" }; // We can assume that these values are unique!
var (a, b, c, d, e) = (new Foo("a"), new Foo("b"), new Foo("c"), new Foo("d"), new Foo("e"));
var input = new List<Foo> { c, b, e, d, a };
var expected = new List<Foo> { e, c, a, b, d };
var actual = input.Sort(t => t.Name, knownValues).ToList();
Console.WriteLine(expected.SequenceEqual(actual) ? "SUCCESS" : "FAIL");
Console.WriteLine("Expected: " + string.Join(", ", expected));
Console.WriteLine("Actual: " + string.Join(", ", actual));
}
}