识别IEnumerable是否已排序的方法

Tos*_*shi 3 c# sorting list

我有这个Extension方法来检查是否对任何类型的List进行了排序

public static bool IsSorted<T>(this IEnumerable<T> input)
{
    IEnumerable<T> expectedListASC = input.OrderBy(x => x);
    IEnumerable<T> expectedListDESC = input.OrderByDescending(x => x);
    return expectedListASC.SequenceEqual(input) || expectedListDESC.SequenceEqual(input);
}
Run Code Online (Sandbox Code Playgroud)

但是对于大型列表,需要时间.是否有更有效的方法来获得相同的结果?

ang*_*son 5

这是一个通用的方法,应该检测序列是按升序还是递减顺序,然后检查集合的其余部分是否也适用.

尚未经过全面测试,您应该向左和向右抛出数据集,如果您决定使用它,请编写单元测试.

public static class CollectionExtensions
{
    public static bool IsOrdered<T>(this IEnumerable<T> collection, IComparer<T> comparer = null)
    {
        comparer = comparer ?? Comparer<T>.Default;

        bool? expectedToIncrease = null;
        using (var enumerator = collection.GetEnumerator())
        {
            bool gotFirst = enumerator.MoveNext();
            if (!gotFirst)
                return true; // empty collection is ordered
            var first = enumerator.Current;
            T second = default(T);

            while (expectedToIncrease is null)
            {
                bool gotSecond = enumerator.MoveNext();
                if (!gotSecond)
                    return true; // only equal elements are ordered
                second = enumerator.Current;

                switch (comparer.Compare(first, second))
                {
                    case int i when i < 0:
                        expectedToIncrease = false;
                        break;

                    case int i when i > 0:
                        expectedToIncrease = true;
                        break;
                }

                if (expectedToIncrease is null)
                    first = second; // prepare for next round
            }

            while (enumerator.MoveNext())
            {
                if (expectedToIncrease.GetValueOrDefault())
                {
                    if (comparer.Compare(second, enumerator.Current) < 0)
                        return false;
                }
                else
                {
                    if (comparer.Compare(second, enumerator.Current) > 0)
                        return false;
                }
            }

            return true;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)