Method that recognized if a IEnumerable is sorted

ienumerable c#
ienumerable<t>
why we use ienumerable in c#
ienumerable to list
ienumerable in mvc
ienumerator in c#
ienumerable linq
ienumerable<string>

I have this Extension method to check if a List of any type is sorted

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);
}

But with large Lists it takes time. Is there a more efficient way to get the same result?

Here's a generic method that ought to detect whether the sequence is in increasing or decreasing order, and then checking if the rest of the collection follows suit.

It has not been fully tested, you should throw datasets to it left and right and write unit-tests if you decide to use this.

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;
        }
    }
}

How to check if a IEnumerable<T> is sorted?, One example of such method could be: static bool IsSorted<T>(IEnumerable<T> enumerable) where T : IComparable<T> { T prev = default(T); bool prevSet  My rationale was clarity of purpose: An array has a notion of ordering, whereas an IEnumerable is implemented by many generic collections, not all of which have a notion of order: Does your extension method need to (1) access the collection out of order? (2) write to the collection? If so, then extend IList<T> If not, extend IEnumerable<T>.

IEnumerable Interface (System.Collections), public interface IEnumerable ImmutableSortedDictionary<TKey,TValue> If your collection does not implement IEnumerable, you must still follow the iterator by providing a GetEnumerator method that returns an interface, class or struct. For the generic version of this interface see System.Collections.Generic.IEnumerable<T>. IEnumerable contains a single method, GetEnumerator, which returns an IEnumerator. IEnumerator provides the ability to iterate through the collection by exposing a Current property and MoveNext and Reset methods.

IOrderedEnumerable<TElement> Interface, An object of type IOrderedEnumerable<TElement> can be obtained by calling one of ThenBy and ThenByDescending, the subordinate sort methods, in turn also return ToImmutableSortedDictionary<TSource,TKey,TValue>(​IEnumerable<  SortedList<TKey,TValue> is implemented as an array of key/value pairs, sorted by the key. Each element can be retrieved as a KeyValuePair<TKey,TValue> object. Key objects must be immutable as long as they are used as keys in the SortedList<TKey,TValue>. Every key in a SortedList<TKey,TValue> must be unique.

Ordered enumeration: IEnumerable or Array (in C#)?, Does your extension method need to (1) access the collection out of order? (2) write to the collection? If so, then extend IList<T> If not, extend  This method uses the Array.Sort method, which applies the introspective sort as follows: If the partition size is less than or equal to 16 elements, it uses an insertion sort algorithm. If the number of partitions exceeds 2 log n, where n is the range of the input array, it uses a Heapsort algorithm. Otherwise, it uses a Quicksort algorithm.

C#, UnionWith(IEnumerable<T>) method is used to modify the current SortedSet<T> object so that it contains all elements that are present in either the current object  IEnumerable<T> contains a single method that you must implement when implementing this interface; GetEnumerator, which returns an IEnumerator<T> object. The returned IEnumerator<T> provides the ability to iterate through the collection by exposing a Current property.

LINQ | Sorting Operator, OrderBy<TSource, TKey>(IEnumerable<TSource>, Func<TSource, TKey>): This method sort the items of the given sequence in ascending order according to  This method compares keys by using the default comparer Default. This method performs a stable sort; that is, if the keys of two elements are equal, the order of the elements is preserved. In contrast, an unstable sort does not preserve the order of elements that have the same key.

Comments
  • Why not just enumerate list and check if following element is always lesser/greater then previous. It would be linear in time (and you can drop checking earlier if not sorted) - for unsorted lists it would be close to const time.
  • Consuming an enumerable multiple times is a) not guaranteed to be possible and b) not guaranteed to be consistent. If you want something solidly generic, your starting point shouldn't be IEnumerable<T>. Even if you change you code to use e.g. ToList() first, your caller still has these problems no matter what you returned. If the caller needs a sorted enumerable, just have them use OrderBY and accept that it may be redundant if the enumerable was already sorted.
  • Possible duplicate of Fastest way to check if an array is sorted
  • @FCin - That isn't a good duplicate in my opinion - the code is easier for a non-generic array of ints, and you don't look for both cases of ascending/descending order.
  • "Sorted" and "ordered by the default comparison" is not necessarily the same... Also, consider to start with a type check for IOrderedEnumerable<T> before you compute anything else.
  • does this differ in ascending and descending?
  • It did, but it's fixed now, so it should check either. Lasse's is probably a little more efficient than mine, however.
  • One note on this - comparer.Compare may return any positive/negative number, so you should use Math.Sign to get just 1, -1, or 0.
  • @Kobi Thanks, fixed :)
  • Thanks for the performance measurement! Now I want to micro-optimize my code. :P