c0rd c0rd - 11 months ago 48
C# Question

Check if a string is sorted

I have a string, simplified

which is sorted. The string couild contain Digits (0-9) or letters (a-z). In case of a mixed use the natural sort order. I need a method to verify if this is true.

Attempt with linq technique:

string items1 = "2349"; //sorted
string items2 = "2476"; //not sorted, 6<>7

bool sorted1 = Enumerable.SequenceEqual(items1.OrderBy(x => x), items1); //true
bool sorted2 = Enumerable.SequenceEqual(items2.OrderBy(x => x), items2); //false

but there could be also a descending sort order.

Is there a better way then

string items3 = "4321";
bool sorted3 = Enumerable.SequenceEqual(items3.OrderBy(x => x), items3) || Enumerable.SequenceEqual(items3.OrderByDescending(x => x), items3);

to check if a string is sorted? Maybe some built in solution?

Answer Source

I once had to check something similar to your case but with huge data streams, so performance was important. I came up with this small extension class which performs very well:

public static bool IsOrdered<T>(this IEnumerable<T> enumerable) where T: IComparable<T>
    using (var enumerator = enumerable.GetEnumerator())
        if (!enumerator.MoveNext())
            return true; //empty enumeration is ordered

        var left = enumerator.Current;
        int previousUnequalComparison = 0;

        while (enumerator.MoveNext())
            var right = enumerator.Current;
            var currentComparison = left.CompareTo(right);

            if (currentComparison != 0)
                if (previousUnequalComparison != 0
                    && currentComparison != previousUnequalComparison)
                    return false;

                previousUnequalComparison = currentComparison;
                left = right;

    return true;

Using it is obviously very simple:

var items1 = "2349";
var items2 = "2476"; //not sorted, 6<>7
items1.IsOrdered(); //true
items2.IsOrdered(); //false