提问者:小点点

我们如何使用LINQ对一些预定义值应该首先出现的列表进行排序呢?


与这个Java问题类似,我想对一个列表进行排序,其中一组已知值应该排在前面(如果存在),然后使用默认顺序,例如equalitycomparer.default。高效的代码是可取的,但我更感兴趣的是巧妙的LINQ表达式。

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

一些小的调整可能是必要的。注意KeySelector,它允许我们选择一个属性作为排序目标。

public static class EnumerableExtensions
{
    public static IEnumerable<T> Sort<T, U>(this IEnumerable<T> input, Func<T, U> keySelector, U[] knownValues)
    {
        // TODO: Clever LINQ implementation here!
        foreach (var item in input)
            yield return item;
    }
}
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));
    }
}

共1个答案

匿名用户

是的。最简单的方法可能是使用

为了简单起见,示例假设这些项是可比较的和相等的,并且输入值和已知值具有相同的类型。

input.OrderBy(i => knownValues.Contains(i) )
      .ThenBy(i => i)